国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

樹(shù)莓派視覺(jué)小車(chē) -- 小球追蹤(顏色追蹤)(OpenCV色彩空間HSV)

developerworks / 1572人閱讀

摘要:一般調(diào)高飽和度會(huì)降低中相對(duì)較低的數(shù)值,凸顯主要顏色的純度。對(duì)當(dāng)前唯一的方法霍夫梯度法,它表示在檢測(cè)階段圓心的累加器閾值。第八個(gè)參數(shù),類型的有默認(rèn)值,表示圓半徑的最小值。

目錄

效果展示?

基礎(chǔ)理論(HSV)

為什么用HSV空間而不是RGB空間?

HSV

1、Hue(色相)

2、Value(明度)

3、Saturation(飽和度)

一、初始化

滑動(dòng)條初始化

1、創(chuàng)建回調(diào)函數(shù)

2、窗口設(shè)置(名稱)?

3、滑動(dòng)條設(shè)置

代碼

二、運(yùn)動(dòng)函數(shù)

三、舵機(jī)控制

四、在HSV空間下獲取二值圖

1、獲取滑動(dòng)條的值

2、轉(zhuǎn)HSV(三通道:H、S、V)

3、轉(zhuǎn)二值圖(單通道閾值處理)

4、結(jié)合HSV三個(gè)通道,得到最終二值圖

代碼

五、圖像處理(總)

1、打開(kāi)攝像頭

2、獲取HSV色彩空間得到的二值圖

3、高斯濾波

4、開(kāi)運(yùn)算去噪

5、閉運(yùn)算

6、霍夫圓檢測(cè)

原理

API

?6-1、霍夫圓檢測(cè)

6-2、獲取圓心和半徑坐標(biāo)

6-3、畫(huà)圓

代碼

六、運(yùn)動(dòng)控制

總代碼


效果展示?

?

?

?

基礎(chǔ)理論(HSV)

為什么用HSV空間而不是RGB空間?

因?yàn)?strong>RGB通道并不能很好地反映出物體具體的顏色信息。

HSV空間能夠非常直觀的表達(dá)色彩的明暗、色調(diào)、以及鮮艷程度,方便進(jìn)行顏色之間的對(duì)比。

(RGB受光線影響很大,所以采取HSV

這里用HSV的目的:得到合適的二值圖

HSV

Hue(H):色調(diào)、色相(具體的顏色)

Saturation(S):飽和度、色彩純凈度

Value(V):明度

Hue范圍是[0,179],飽和范圍是[0,255],值范圍是[0,255]

(寫(xiě)代碼的時(shí)候,犯了蠢錯(cuò)誤:把3個(gè)都設(shè)成了179,發(fā)現(xiàn)死活調(diào)不對(duì))

1、Hue(色相)

Hue:色相(具體的顏色)


2、Value(明度)

明度:色彩的明亮程度,單通道亮度(并不等同于整體發(fā)光量)。

(明度越高越白,越低越黑,一般提高明度會(huì)同時(shí)提高R、G、B三通道的數(shù)值)

3、Saturation(飽和度)

Saturation:飽和度、色彩純度(越低越灰,越高越純)??。

(一般調(diào)高飽和度會(huì)降低RGB中相對(duì)較低的數(shù)值,凸顯主要顏色的純度。 )

B站視頻講解:

短動(dòng)畫(huà)慢語(yǔ)速1分鐘講清影視調(diào)色中色彩形成原理基礎(chǔ)——RGB與HSV

一、初始化

滑動(dòng)條初始化

這次的初始化,除了電機(jī)、舵機(jī)、窗口等等的初始化,還有滑動(dòng)條的初始設(shè)置。?

在創(chuàng)建滑動(dòng)條之前:

1、需要設(shè)置窗口名稱,不然窗口都沒(méi)有,自然也就無(wú)法設(shè)置滑動(dòng)條了。

2、創(chuàng)建回調(diào)函數(shù)。

1、創(chuàng)建回調(diào)函數(shù)

def nothing(*arg):    pass

2、窗口設(shè)置(名稱)?

def Trackbar_Init():    # 1 create windows    cv2.namedWindow("h_binary")    cv2.namedWindow("s_binary")    cv2.namedWindow("v_binary")

3、滑動(dòng)條設(shè)置

# 2 Create Trackbar    cv2.createTrackbar("hmin", "h_binary", 6, 179, nothing)      cv2.createTrackbar("hmax", "h_binary", 26, 179, nothing)      cv2.createTrackbar("smin", "s_binary", 110, 255, nothing)    cv2.createTrackbar("smax", "s_binary", 255, 255, nothing)    cv2.createTrackbar("vmin", "v_binary", 140, 255, nothing)    cv2.createTrackbar("vmax", "v_binary", 255, 255, nothing)    #   創(chuàng)建滑動(dòng)條     滑動(dòng)條值名稱 窗口名稱   滑動(dòng)條值 滑動(dòng)條閾值 回調(diào)函數(shù)

代碼

def Motor_Init():    global L_Motor, R_Motor    L_Motor= GPIO.PWM(l_motor,100)    R_Motor = GPIO.PWM(r_motor,100)    L_Motor.start(0)    R_Motor.start(0)def Direction_Init():    GPIO.setup(left_back,GPIO.OUT)    GPIO.setup(left_front,GPIO.OUT)    GPIO.setup(l_motor,GPIO.OUT)        GPIO.setup(right_front,GPIO.OUT)    GPIO.setup(right_back,GPIO.OUT)    GPIO.setup(r_motor,GPIO.OUT)def Servo_Init():    global pwm_servo    pwm_servo=Adafruit_PCA9685.PCA9685()def Trackbar_Init():    # 1 create windows    cv2.namedWindow("h_binary")    cv2.namedWindow("s_binary")    cv2.namedWindow("v_binary")    # 2 Create Trackbar    cv2.createTrackbar("hmin", "h_binary", 6, 179, nothing)      cv2.createTrackbar("hmax", "h_binary", 26, 179, nothing)      cv2.createTrackbar("smin", "s_binary", 110, 255, nothing)    cv2.createTrackbar("smax", "s_binary", 255, 255, nothing)    cv2.createTrackbar("vmin", "v_binary", 140, 255, nothing)    cv2.createTrackbar("vmax", "v_binary", 255, 255, nothing)    #   創(chuàng)建滑動(dòng)條     滑動(dòng)條值名稱 窗口名稱   滑動(dòng)條值 滑動(dòng)條閾值 回調(diào)函數(shù)def Init():    GPIO.setwarnings(False)     GPIO.setmode(GPIO.BCM)    Direction_Init()    Servo_Init()    Motor_Init()    Trackbar_Init()# 回調(diào)函數(shù)def nothing(*arg):    pass

二、運(yùn)動(dòng)函數(shù)

常規(guī)操作:向前、向后、向左、向右、停止。?

def Front(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,1)   #left_front    GPIO.output(left_back,0)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,1)  #right_front    GPIO.output(right_back,0)   #right_back         def Back(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,0)   #left_front    GPIO.output(left_back,1)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,0)  #right_front    GPIO.output(right_back,1)   #right_backdef Left(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,0)   #left_front    GPIO.output(left_back,1)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,1)  #right_front    GPIO.output(right_back,0)   #right_backdef Right(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,1)   #left_front    GPIO.output(left_back,0)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,0)  #right_front    GPIO.output(right_back,1)   #right_backdef Stop():    L_Motor.ChangeDutyCycle(0)    GPIO.output(left_front,0)   #left_front    GPIO.output(left_back,0)    #left_back    R_Motor.ChangeDutyCycle(0)    GPIO.output(right_front,0)  #right_front    GPIO.output(right_back,0)   #right_back    

三、舵機(jī)控制

def set_servo_angle(channel,angle):    angle=4096*((angle*11)+500)/20000    pwm_servo.set_pwm_freq(50)                #frequency==50Hz (servo)    pwm_servo.set_pwm(channel,0,int(angle))
set_servo_angle(4, 110)     #top servo     lengthwise    #0:back    180:front        set_servo_angle(5, 90)     #bottom servo  crosswise    #0:left    180:right  

四、在HSV空間下獲取二值圖

1、獲取滑動(dòng)條的值

# 1 get trackbar"s value    hmin = cv2.getTrackbarPos("hmin", "h_binary")    hmax = cv2.getTrackbarPos("hmax", "h_binary")    smin = cv2.getTrackbarPos("smin", "s_binary")    smax = cv2.getTrackbarPos("smax", "s_binary")    vmin = cv2.getTrackbarPos("vmin", "v_binary")    vmax = cv2.getTrackbarPos("vmax", "v_binary")

2、轉(zhuǎn)HSV(三通道:H、S、V)

# 2 to HSV    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)    cv2.imshow("hsv", hsv)    h, s, v = cv2.split(hsv)

?

3、轉(zhuǎn)二值圖(單通道閾值處理)

分別對(duì)H、S、V三個(gè)道閾值處理:

# 3 set threshold (binary image)    # if value in (min, max):white; otherwise:black    h_binary = cv2.inRange(np.array(h), np.array(hmin), np.array(hmax))    s_binary = cv2.inRange(np.array(s), np.array(smin), np.array(smax))    v_binary = cv2.inRange(np.array(v), np.array(vmin), np.array(vmax))# 5 Show    cv2.imshow("h_binary", h_binary)    cv2.imshow("s_binary", s_binary)    cv2.imshow("v_binary", v_binary)

4、結(jié)合HSV三個(gè)通道,得到最終二值圖

對(duì)H、S、V三個(gè)通道與操作。(H&&S&&V)

# 4 get binary    binary = cv2.bitwise_and(h_binary, cv2.bitwise_and(s_binary, v_binary))

代碼

# 在HSV色彩空間下得到二值圖def Get_HSV(image):    # 1 get trackbar"s value    hmin = cv2.getTrackbarPos("hmin", "h_binary")    hmax = cv2.getTrackbarPos("hmax", "h_binary")    smin = cv2.getTrackbarPos("smin", "s_binary")    smax = cv2.getTrackbarPos("smax", "s_binary")    vmin = cv2.getTrackbarPos("vmin", "v_binary")    vmax = cv2.getTrackbarPos("vmax", "v_binary")        # 2 to HSV    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)    cv2.imshow("hsv", hsv)    h, s, v = cv2.split(hsv)        # 3 set threshold (binary image)    # if value in (min, max):white; otherwise:black    h_binary = cv2.inRange(np.array(h), np.array(hmin), np.array(hmax))    s_binary = cv2.inRange(np.array(s), np.array(smin), np.array(smax))    v_binary = cv2.inRange(np.array(v), np.array(vmin), np.array(vmax))        # 4 get binary(對(duì)H、S、V三個(gè)通道分別與操作)    binary = cv2.bitwise_and(h_binary, cv2.bitwise_and(s_binary, v_binary))        # 5 Show    cv2.imshow("h_binary", h_binary)    cv2.imshow("s_binary", s_binary)    cv2.imshow("v_binary", v_binary)    cv2.imshow("binary", binary)        return binary

五、圖像處理(總)

1、打開(kāi)攝像頭

# 1 Capture the frames    ret, frame = camera.read()    image = frame    cv2.imshow("frame", frame)

2、獲取HSV色彩空間得到的二值圖

(Get_HSV(frame)其實(shí)就是步驟四的HSV處理)

# 2 get HSV    binary = Get_HSV(frame)

3、高斯濾波

# 3 Gausi blur    blur = cv2.GaussianBlur(binary,(9,9),0)

4、開(kāi)運(yùn)算去噪

# 4 Open    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))    Open = cv2.morphologyEx(blur, cv2.MORPH_OPEN, kernel)    cv2.imshow("Open",Open)

5、閉運(yùn)算

# 5 Close    Close = cv2.morphologyEx(Open, cv2.MORPH_CLOSE, kernel)    cv2.imshow("Close",Close)

?

6、霍夫圓檢測(cè)

原理

霍夫變換圓檢測(cè)是基于圖像梯度實(shí)現(xiàn):

圓心檢測(cè)的原理︰圓心是圓周法線的交匯處設(shè)置一個(gè)閾值在某點(diǎn)的相交的直線的條數(shù)大于這個(gè)閾值就認(rèn)為該交匯點(diǎn)為圓心
圓半徑確定原理:圓心到圓周上的距離〔半徑)是相同的設(shè)置一個(gè)閾值只要相同距離的數(shù)量大于該閾值就認(rèn)為該距離是該圓心的半徑

API

def HoughCircles(image: Any,                 method: Any,                 dp: Any,                 minDist: Any,                 circles: Any = None,                 param1: Any = None,                 param2: Any = None,                 minRadius: Any = None,                 maxRadius: Any = None) -> None

參數(shù):?

  • 第二個(gè)參數(shù),int類型的method,即使用的檢測(cè)方法,目前OpenCV中就霍夫梯度法一種可以使用,它的標(biāo)識(shí)符為CV_HOUGH_GRADIENT,在此參數(shù)處填這個(gè)標(biāo)識(shí)符即可。
  • 第三個(gè)參數(shù),double類型的dp,用來(lái)檢測(cè)圓心的累加器圖像的分辨率于輸入圖像之比的倒數(shù),且此參數(shù)允許創(chuàng)建一個(gè)比輸入圖像分辨率低的累加器。上述文字不好理解的話,來(lái)看例子吧。例如,如果dp= 1時(shí),累加器和輸入圖像具有相同的分辨率。如果dp=2,累加器便有輸入圖像一半那么大的寬度和高度。
  • 第四個(gè)參數(shù),double類型的minDist,為霍夫變換檢測(cè)到的圓的圓心之間的最小距離,即讓我們的算法能明顯區(qū)分的兩個(gè)不同圓之間的最小距離。這個(gè)參數(shù)如果太小的話,多個(gè)相鄰的圓可能被錯(cuò)誤地檢測(cè)成了一個(gè)重合的圓。反之,這個(gè)參數(shù)設(shè)置太大的話,某些圓就不能被檢測(cè)出來(lái)了。
  • 第五個(gè)參數(shù),InputArray類型的circles,經(jīng)過(guò)調(diào)用HoughCircles函數(shù)后此參數(shù)存儲(chǔ)了檢測(cè)到的圓的輸出矢量,每個(gè)矢量由包含了3個(gè)元素的浮點(diǎn)矢量(x, y, radius)表示。
  • 第六個(gè)參數(shù),double類型的param1,有默認(rèn)值100。它是第三個(gè)參數(shù)method設(shè)置的檢測(cè)方法的對(duì)應(yīng)的參數(shù)。對(duì)當(dāng)前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示傳遞給canny邊緣檢測(cè)算子的高閾值,而低閾值為高閾值的一半。
  • 第七個(gè)參數(shù),double類型的param2,也有默認(rèn)值100。它是第三個(gè)參數(shù)method設(shè)置的檢測(cè)方法的對(duì)應(yīng)的參數(shù)。對(duì)當(dāng)前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示在檢測(cè)階段圓心的累加器閾值。它越小的話,就可以檢測(cè)到更多根本不存在的圓,而它越大的話,能通過(guò)檢測(cè)的圓就更加接近完美的圓形了
  • 第八個(gè)參數(shù),int類型的minRadius,有默認(rèn)值0,表示圓半徑的最小值
  • 第九個(gè)參數(shù),int類型的maxRadius,也有默認(rèn)值0,表示圓半徑的最大值

?6-1、霍夫圓檢測(cè)

# 6 Hough Circle detect    circles = cv2.HoughCircles(Close,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=20,minRadius=20,maxRadius=0)    #                                                                     param2:決定圓能否被檢測(cè)到(越少越容易檢測(cè)到圓,但相應(yīng)的也更容易出錯(cuò))

6-2、獲取圓心和半徑坐標(biāo)

# 1 獲取圓的圓心和半徑        x, y, r = int(circles[0][0][0]),int(circles[0][0][1]),int(circles[0][0][2])        print(x, y, r)

6-3、畫(huà)圓

# 2 畫(huà)圓        cv2.circle(image, (x, y), r, (255,0,255),5)        cv2.imshow("image", image)

代碼

# 圖像處理def Image_Processing():    global h, s, v    # 1 Capture the frames    ret, frame = camera.read()    image = frame    cv2.imshow("frame", frame)        # 2 get HSV    binary = Get_HSV(frame)        # 3 Gausi blur    blur = cv2.GaussianBlur(binary,(9,9),0)        # 4 Open    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))    Open = cv2.morphologyEx(blur, cv2.MORPH_OPEN, kernel)    cv2.imshow("Open",Open)    # 5 Close    Close = cv2.morphologyEx(Open, cv2.MORPH_CLOSE, kernel)    cv2.imshow("Close",Close)    # 6 Hough Circle detect    circles = cv2.HoughCircles(Close,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=20,minRadius=20,maxRadius=0)    #                                                                     param2:決定圓能否被檢測(cè)到(越少越容易檢測(cè)到圓,但相應(yīng)的也更容易出錯(cuò))    # judge if circles is exist    if circles is not None:        # 1 獲取圓的圓心和半徑        x, y, r = int(circles[0][0][0]),int(circles[0][0][1]),int(circles[0][0][2])        print(x, y, r)        # 2 畫(huà)圓        cv2.circle(image, (x, y), r, (255,0,255),5)        cv2.imshow("image", image)    else:        (x,y),r = (0,0), 0            return (x,y), r

六、運(yùn)動(dòng)控制

根據(jù)檢測(cè)到的圓,獲取到的坐標(biāo)、半徑,進(jìn)行運(yùn)動(dòng)控制。

這里可以做到跟蹤小球,前進(jìn)和后退相配合,“敵進(jìn)我退,敵退我進(jìn)”。

# 運(yùn)動(dòng)控制(這里可以做到跟蹤小球,前景和后退相配合,“敵進(jìn)我退,敵退我進(jìn)”)def Move((x,y), r):    low_xlimit = width/4    high_xlimit = 0.75 * width    #low_ylimit = 3/4 * height    ylimit = 0.75 * height    print(high_xlimit, ylimit)    # 沒(méi)檢測(cè)到,停止不動(dòng)    if x==0:        Stop()    # 檢測(cè)到在圖片0.75以上的區(qū)域(距離正常)    elif x>low_xlimit and xlow_xlimit and x=ylimit:        Back(60)    # 在左0.25區(qū)域,向左跟蹤    elif xhigh_xlimit:        Right(60)

總代碼

#Ball Tracking(HSV)import  RPi.GPIO as GPIOimport timeimport Adafruit_PCA9685import numpy as npimport cv2#set capture windowwidth, height = 320, 240camera = cv2.VideoCapture(0)camera.set(3,width) camera.set(4,height) l_motor = 18left_front   =  22left_back   =  27r_motor = 23right_front   = 25right_back  =  24def Motor_Init():    global L_Motor, R_Motor    L_Motor= GPIO.PWM(l_motor,100)    R_Motor = GPIO.PWM(r_motor,100)    L_Motor.start(0)    R_Motor.start(0)def Direction_Init():    GPIO.setup(left_back,GPIO.OUT)    GPIO.setup(left_front,GPIO.OUT)    GPIO.setup(l_motor,GPIO.OUT)        GPIO.setup(right_front,GPIO.OUT)    GPIO.setup(right_back,GPIO.OUT)    GPIO.setup(r_motor,GPIO.OUT)def Servo_Init():    global pwm_servo    pwm_servo=Adafruit_PCA9685.PCA9685()def Trackbar_Init():    # 1 create windows    cv2.namedWindow("h_binary")    cv2.namedWindow("s_binary")    cv2.namedWindow("v_binary")    # 2 Create Trackbar    cv2.createTrackbar("hmin", "h_binary", 6, 179, nothing)      cv2.createTrackbar("hmax", "h_binary", 26, 179, nothing)      cv2.createTrackbar("smin", "s_binary", 110, 255, nothing)    cv2.createTrackbar("smax", "s_binary", 255, 255, nothing)    cv2.createTrackbar("vmin", "v_binary", 140, 255, nothing)    cv2.createTrackbar("vmax", "v_binary", 255, 255, nothing)    #   創(chuàng)建滑動(dòng)條     滑動(dòng)條值名稱 窗口名稱   滑動(dòng)條值 滑動(dòng)條閾值 回調(diào)函數(shù)def Init():    GPIO.setwarnings(False)     GPIO.setmode(GPIO.BCM)    Direction_Init()    Servo_Init()    Motor_Init()    Trackbar_Init()def Front(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,1)   #left_front    GPIO.output(left_back,0)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,1)  #right_front    GPIO.output(right_back,0)   #right_back         def Back(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,0)   #left_front    GPIO.output(left_back,1)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,0)  #right_front    GPIO.output(right_back,1)   #right_backdef Left(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,0)   #left_front    GPIO.output(left_back,1)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,1)  #right_front    GPIO.output(right_back,0)   #right_backdef Right(speed):    L_Motor.ChangeDutyCycle(speed)    GPIO.output(left_front,1)   #left_front    GPIO.output(left_back,0)    #left_back    R_Motor.ChangeDutyCycle(speed)    GPIO.output(right_front,0)  #right_front    GPIO.output(right_back,1)   #right_backdef Stop():    L_Motor.ChangeDutyCycle(0)    GPIO.output(left_front,0)   #left_front    GPIO.output(left_back,0)    #left_back    R_Motor.ChangeDutyCycle(0)    GPIO.output(right_front,0)  #right_front    GPIO.output(right_back,0)   #right_backdef set_servo_angle(channel,angle):    angle=4096*((angle*11)+500)/20000    pwm_servo.set_pwm_freq(50)                #frequency==50Hz (servo)    pwm_servo.set_pwm(channel,0,int(angle))# 回調(diào)函數(shù)def nothing(*arg):    pass# 在HSV色彩空間下得到二值圖def Get_HSV(image):    # 1 get trackbar"s value    hmin = cv2.getTrackbarPos("hmin", "h_binary")    hmax = cv2.getTrackbarPos("hmax", "h_binary")    smin = cv2.getTrackbarPos("smin", "s_binary")    smax = cv2.getTrackbarPos("smax", "s_binary")    vmin = cv2.getTrackbarPos("vmin", "v_binary")    vmax = cv2.getTrackbarPos("vmax", "v_binary")        # 2 to HSV    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)    cv2.imshow("hsv", hsv)    h, s, v = cv2.split(hsv)        # 3 set threshold (binary image)    # if value in (min, max):white; otherwise:black    h_binary = cv2.inRange(np.array(h), np.array(hmin), np.array(hmax))    s_binary = cv2.inRange(np.array(s), np.array(smin), np.array(smax))    v_binary = cv2.inRange(np.array(v), np.array(vmin), np.array(vmax))        # 4 get binary(對(duì)H、S、V三個(gè)通道分別與操作)    binary = cv2.bitwise_and(h_binary, cv2.bitwise_and(s_binary, v_binary))        # 5 Show    cv2.imshow("h_binary", h_binary)    cv2.imshow("s_binary", s_binary)    cv2.imshow("v_binary", v_binary)    cv2.imshow("binary", binary)        return binary# 圖像處理def Image_Processing():    global h, s, v    # 1 Capture the frames    ret, frame = camera.read()    image = frame    cv2.imshow("frame", frame)        # 2 get HSV    binary = Get_HSV(frame)        # 3 Gausi blur    blur = cv2.GaussianBlur(binary,(9,9),0)        # 4 Open    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))    Open = cv2.morphologyEx(blur, cv2.MORPH_OPEN, kernel)    cv2.imshow("Open",Open)    # 5 Close    Close = cv2.morphologyEx(Open, cv2.MORPH_CLOSE, kernel)    cv2.imshow("Close",Close)    # 6 Hough Circle detect    circles = cv2.HoughCircles(Close,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=20,minRadius=20,maxRadius=0)    #                                                                     param2:決定圓能否被檢測(cè)到(越少越容易檢測(cè)到圓,但相應(yīng)的也更容易出錯(cuò))    # judge if circles is exist    if circles is not None:        # 1 獲取圓的圓心和半徑        x, y, r = int(circles[0][0][0]),int(circles[0][0][1]),int(circles[0][0][2])        print(x, y, r)        # 2 畫(huà)圓        cv2.circle(image, (x, y), r, (255,0,255),5)        cv2.imshow("image", image)    else:        (x,y),r = (0,0), 0            return (x,y), r# 運(yùn)動(dòng)控制(這里可以做到跟蹤小球,前景和后退相配合,“敵進(jìn)我退,敵退我進(jìn)”)def Move((x,y), r):    low_xlimit = width/4    high_xlimit = 0.75 * width    #low_ylimit = 3/4 * height    ylimit = 0.75 * height    print(high_xlimit, ylimit)    # 沒(méi)檢測(cè)到,停止不動(dòng)    if x==0:        Stop()    # 檢測(cè)到在圖片0.75以上的區(qū)域(距離正常)    elif x>low_xlimit and xlow_xlimit and x=ylimit:        Back(60)    # 在左0.25區(qū)域,向左跟蹤    elif xhigh_xlimit:        Right(60)    if __name__ == "__main__":    Init()        set_servo_angle(4, 110)     #top servo     lengthwise    #0:back    180:front        set_servo_angle(5, 90)     #bottom servo  crosswise    #0:left    180:right          while 1:        # 1 Image Process        (x,y), r = Image_Processing()                # 2 Move        Move((x,y), r)                # must include this codes(otherwise you can"t open camera successfully)        if cv2.waitKey(1) & 0xFF == ord("q"):            Stop()            GPIO.cleanup()                break

這里的HSV是根據(jù)我自己當(dāng)前的情況調(diào)節(jié)的,更改場(chǎng)景以后可能需要重新調(diào)節(jié)H、S、V三通道的閾值(max && min)

基礎(chǔ)的視覺(jué)檢測(cè)+運(yùn)動(dòng),沒(méi)有太多的運(yùn)動(dòng)控制算法(PID等等都沒(méi)有涉及到)。有好的想法和建議歡迎交流討論,Thanks?(?ω?)?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/119986.html

相關(guān)文章

  • 分享 | 撞壞遙控車(chē)后,有個(gè)技術(shù)大牛爸爸是種怎樣的體驗(yàn)

    摘要:在我已經(jīng)制作完成一輛可以運(yùn)行的遙控車(chē)時(shí),公司發(fā)布了一個(gè)自駕車(chē)項(xiàng)目,來(lái)展示自動(dòng)駕駛汽車(chē)的工作原理。需要注意的是,這里用的都是語(yǔ)言而非,其主要原因有兩個(gè)一方面,近來(lái)似乎已成為運(yùn)用機(jī)器學(xué)習(xí)技術(shù)時(shí)實(shí)際使用的語(yǔ)言。 最近,Mapbox 的 Android 工程師 Antonio 使用計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)技術(shù),為他的女兒 Violeta 重新制作了一臺(tái)遙控車(chē)。接下來(lái)我們看看 Antonio 是如何...

    ConardLi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<