千家信息网

怎么实现OpenCV物体跟踪树莓派视觉小车效果

发表于:2025-11-09 作者:千家信息网编辑
千家信息网最后更新 2025年11月09日,这篇文章主要讲解了"怎么实现OpenCV物体跟踪树莓派视觉小车效果",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么实现OpenCV物体跟踪树莓派视觉
千家信息网最后更新 2025年11月09日怎么实现OpenCV物体跟踪树莓派视觉小车效果

这篇文章主要讲解了"怎么实现OpenCV物体跟踪树莓派视觉小车效果",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么实现OpenCV物体跟踪树莓派视觉小车效果"吧!

目录
  • 一、初始化

  • 二、运动控制函数

  • 三、舵机角度控制

  • 四、摄像头&&图像处理

    • 1、打开摄像头

    • 2、把图像转换为灰度图

    • 3、 高斯滤波(去噪)

    • 4、亮度增强

    • 5、转换为二进制

    • 6、闭运算处理

    • 7、获取轮廓

    • 代码

  • 五、获取最大轮廓坐标

    • 六、运动

      • 1、没有识别到轮廓(静止)

      • 2、向前走

      • 3、向左转

      • 4、向右转

      • 代码

    • 总代码

    一、初始化

    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_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_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))
    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):是顶部的舵机(摄像头上下摆动的那个舵机)

    下面的(5):是底部的舵机(摄像头左右摆动的那个舵机)

    四、摄像头&&图像处理

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

    1、打开摄像头

    打开摄像头,并设置窗口大小。

    设置小窗口的原因: 小窗口实时性比较好。

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

    2、把图像转换为灰度图

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

    3、 高斯滤波(去噪)

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

    4、亮度增强

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

    5、转换为二进制

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

    6、闭运算处理

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

    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)

    代码

    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

    五、获取最大轮廓坐标

    由于有可能出现多个物体,我们这里只识别最大的物体(深度学习可以搞分类,还没学到这,学到了再做),得到它的坐标。

    # 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

    返回最大轮廓的坐标:

    六、运动

    根据反馈回来的坐标,判断它的位置,进行运动。

    # 3 Move        Move(x,y)

    1、没有识别到轮廓(静止)

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

    2、向前走

    识别到物体,且在正中央(中间1/2区域),让物体向前走。

    #go ahead    elif width/4 

    3、向左转

    物体在左边1/4区域。

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

    4、向右转

    物体在右边1/4区域。

    #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  (width-width/4):        Right(50)

    总代码

    #Object Trackingimport  RPi.GPIO as GPIOimport timeimport Adafruit_PCA9685import numpy as npimport cv2second = 0 width, height = 160, 120camera = cv2.VideoCapture(0)camera.set(3,width) camera.set(4,height) l_motor = 18left_front   =  22left_back   =  27r_motor = 23right_front   = 25right_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_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)) 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, contoursdef 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  (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()

    检测原理是基于最大轮廓的检测,没有用深度学习的分类,所以容易受到干扰,后期学完深度学习会继续优化。有意见或者想法的朋友欢迎交流。

    感谢各位的阅读,以上就是"怎么实现OpenCV物体跟踪树莓派视觉小车效果"的内容了,经过本文的学习后,相信大家对怎么实现OpenCV物体跟踪树莓派视觉小车效果这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

    物体 轮廓 摄像头 摄像 舵机 学习 最大 坐标 运动 小车 效果 树莓 视觉 跟踪 代码 图像 处理 控制 区域 深度 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海迈程网络技术有限公司 上海专业软件开发周期 校园网络安全平台登录入口 服务器每秒200请求 服务器安全证怎么办 网络安全审查及准入机制 免费观看直播软件开发的 网络安全月宣传展板 外派到沃尔玛做软件开发好吗 软件开发可行性分析一般来说 众奥通网络技术培训橙子老师 建党百年做好校园网络安全 网吧后面的服务器 服务器报警原点异常怎么排除 软件开发京东方面试 国外网络安全法律教育 目前网络安全的主要威胁 服务器无法连接无线网卡 搭建人工智能网络安全体系 广州泽诺互联网科技有限公司 excel表可以做数据库 软件开发毕业生职业规划 山西智慧人口系统软件开发 sql数据库中ddl是什么意思 笛卡尔积在数据库中的用法 天上网络技术有限公司 湖南pdu服务器电源厂家有哪些 软件开发转型做什么工作好 七日杀 服务器管理员 南方航天公司软件开发待遇
    0