溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

發(fā)布時(shí)間:2021-10-18 12:17:38 來源:億速云 閱讀:242 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果”吧!

目錄
  • 一、初始化

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

  • 三、舵機(jī)角度控制

  • 四、攝像頭&&圖像處理

    • 1、打開攝像頭

    • 2、把圖像轉(zhuǎn)換為灰度圖

    • 3、 高斯濾波(去噪)

    • 4、亮度增強(qiáng)

    • 5、轉(zhuǎn)換為二進(jìn)制

    • 6、閉運(yùn)算處理

    • 7、獲取輪廓

    • 代碼

  • 五、獲取最大輪廓坐標(biāo)

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

      • 1、沒有識別到輪廓(靜止)

      • 2、向前走

      • 3、向左轉(zhuǎn)

      • 4、向右轉(zhuǎn)

      • 代碼

    • 總代碼

    一、初始化

    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 Init():
        GPIO.setwarnings(False) 
        GPIO.setmode(GPIO.BCM)
        Direction_Init()
        Servo_Init()
        Motor_Init()

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

    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_back 
    def 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_back
    def 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_back 
    def 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

    上面的(4):是頂部的舵機(jī)(攝像頭上下擺動(dòng)的那個(gè)舵機(jī))

    下面的(5):是底部的舵機(jī)(攝像頭左右擺動(dòng)的那個(gè)舵機(jī))

    四、攝像頭&&圖像處理

    # 1 Image Process
            img, contours = Image_Processing()
    width, height = 160, 120
        camera = cv2.VideoCapture(0)
        camera.set(3,width) 
        camera.set(4,height)

    1、打開攝像頭

    打開攝像頭,并設(shè)置窗口大小。

    設(shè)置小窗口的原因: 小窗口實(shí)時(shí)性比較好。

    # Capture the frames
        ret, frame = camera.read()

    怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

    2、把圖像轉(zhuǎn)換為灰度圖

    # to gray
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow('gray',gray)

    怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

    3、 高斯濾波(去噪)

    # Gausi blur
        blur = cv2.GaussianBlur(gray,(5,5),0)

    4、亮度增強(qiáng)

    #brighten
        blur = cv2.convertScaleAbs(blur, None, 1.5, 30)

    5、轉(zhuǎn)換為二進(jìn)制

    #to binary
        ret,binary = cv2.threshold(blur,150,255,cv2.THRESH_BINARY_INV)
        cv2.imshow('binary',binary)

    怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

    6、閉運(yùn)算處理

    #Close
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))
        close = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
        cv2.imshow('close',close)

    怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

    7、獲取輪廓

    #get contours
        binary_c,contours,hierarchy = cv2.findContours(close, 1, cv2.CHAIN_APPROX_NONE)
        cv2.drawContours(image, contours, -1, (255,0,255), 2)
        cv2.imshow('image', image)

    怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

    代碼

    def Image_Processing():
        # Capture the frames
        ret, frame = camera.read()
        # Crop the image
        image = frame
        cv2.imshow('frame',frame)
        # to gray
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('gray',gray)
        # Gausi blur
        blur = cv2.GaussianBlur(gray,(5,5),0)
        #brighten
        blur = cv2.convertScaleAbs(blur, None, 1.5, 30)
        #to binary
        ret,binary = cv2.threshold(blur,150,255,cv2.THRESH_BINARY_INV)
        cv2.imshow('binary',binary)
        #Close
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))
        close = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
        cv2.imshow('close',close)
        #get contours
        binary_c,contours,hierarchy = cv2.findContours(close, 1, cv2.CHAIN_APPROX_NONE)
        cv2.drawContours(image, contours, -1, (255,0,255), 2)
        cv2.imshow('image', image)
        return frame, contours

    五、獲取最大輪廓坐標(biāo)

    由于有可能出現(xiàn)多個(gè)物體,我們這里只識別最大的物體(深度學(xué)習(xí)可以搞分類,還沒學(xué)到這,學(xué)到了再做),得到它的坐標(biāo)。

    # 2 get coordinates
            x, y = Get_Coord(img, contours)
    def Get_Coord(img, contours):
        image = img.copy()
        try:
            contour = max(contours, key=cv2.contourArea)
            cv2.drawContours(image, contour, -1, (255,0,255), 2)
            cv2.imshow('new_frame', image)
            # get coord
            M = cv2.moments(contour)
            x = int(M['m10']/M['m00'])
            y = int(M['m01']/M['m00'])
            print(x, y) 
            return x,y
            
        except:
            print 'no objects'
            return 0,0

    返回最大輪廓的坐標(biāo):

    怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果

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

    根據(jù)反饋回來的坐標(biāo),判斷它的位置,進(jìn)行運(yùn)動(dòng)。

    # 3 Move
            Move(x,y)

    1、沒有識別到輪廓(靜止)

    if x==0 and y==0:
            Stop()

    2、向前走

    識別到物體,且在正中央(中間1/2區(qū)域),讓物體向前走。

    #go ahead
        elif width/4 <x and x<(width-width/4):
            Front(70)

    3、向左轉(zhuǎn)

    物體在左邊1/4區(qū)域。

    #left
        elif x < width/4:
            Left(50)

    4、向右轉(zhuǎn)

    物體在右邊1/4區(qū)域。

    #Right
        elif x > (width-width/4):
            Right(50)

    代碼

    def Move(x,y):
        global second
        #stop
        if x==0 and y==0:
            Stop()
        #go ahead
        elif width/4 <x and x<(width-width/4):
            Front(70)
        #left
        elif x < width/4:
            Left(50)
        #Right
        elif x > (width-width/4):
            Right(50)

    總代碼

    #Object Tracking
    import  RPi.GPIO as GPIO
    import time
    import Adafruit_PCA9685
    import numpy as np
    import cv2
    second = 0 
    width, height = 160, 120
    camera = cv2.VideoCapture(0)
    camera.set(3,width) 
    camera.set(4,height) 
    l_motor = 18
    left_front   =  22
    left_back   =  27
    r_motor = 23
    right_front   = 25
    right_back  =  24 
    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 Init():
        GPIO.setwarnings(False) 
        GPIO.setmode(GPIO.BCM)
        Direction_Init()
        Servo_Init()
        Motor_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_back 
    def 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_back  
    def 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_back
    def 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
    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)) 
    def Image_Processing():
        # Capture the frames
        ret, frame = camera.read()
        # Crop the image
        image = frame
        cv2.imshow('frame',frame)
        # to gray
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('gray',gray)
        # Gausi blur
        blur = cv2.GaussianBlur(gray,(5,5),0)
        #brighten
        blur = cv2.convertScaleAbs(blur, None, 1.5, 30)
        #to binary
        ret,binary = cv2.threshold(blur,150,255,cv2.THRESH_BINARY_INV)
        cv2.imshow('binary',binary)
        #Close
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))
        close = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
        cv2.imshow('close',close)
        #get contours
        binary_c,contours,hierarchy = cv2.findContours(close, 1, cv2.CHAIN_APPROX_NONE)
        cv2.drawContours(image, contours, -1, (255,0,255), 2)
        cv2.imshow('image', image)
        return frame, contours
    def Get_Coord(img, contours):
        image = img.copy()
        try:
            contour = max(contours, key=cv2.contourArea)
            cv2.drawContours(image, contour, -1, (255,0,255), 2)
            cv2.imshow('new_frame', image)
            # get coord
            M = cv2.moments(contour)
            x = int(M['m10']/M['m00'])
            y = int(M['m01']/M['m00'])
            print(x, y) 
            return x,y        
        except:
            print 'no objects'
            return 0,0    
    def Move(x,y):
        global second
        #stop
        if x==0 and y==0:
            Stop()
        #go ahead
        elif width/4 <x and x<(width-width/4):
            Front(70)
        #left
        elif x < width/4:
            Left(50)
        #Right
        elif x > (width-width/4):
            Right(50)   
    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
            img, contours = Image_Processing() 
            # 2 get coordinates
            x, y = Get_Coord(img, contours)
            # 3 Move
            Move(x,y)       
            # must include this codes(otherwise you can't open camera successfully)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                Stop()
                GPIO.cleanup()    
                break    
        #Front(50)
        #Back(50)
        #$Left(50)
        #Right(50)
        #time.sleep(1)
        #Stop()

    檢測原理是基于最大輪廓的檢測,沒有用深度學(xué)習(xí)的分類,所以容易受到干擾,后期學(xué)完深度學(xué)習(xí)會(huì)繼續(xù)優(yōu)化。有意見或者想法的朋友歡迎交流。

    感謝各位的閱讀,以上就是“怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么實(shí)現(xiàn)OpenCV物體跟蹤樹莓派視覺小車效果這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI