目录

物体跟踪效果展示

过程:

一、初始化

二、运动控制函数

三、舵机角度控制

四、摄像头&&图像处理

1、打开摄像头

2、把图像转换为灰度图

3、 高斯滤波(去噪)

4、亮度增强

5、转换为二进制

6、闭运算处理

7、获取轮廓

代码

五、获取最大轮廓坐标

六、运动

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

2、向前走

3、向左转

4、向右转

代码

总代码


物体跟踪效果展示

  

过程:

一、初始化

def Motor_Init():global L_Motor, R_MotorL_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_servopwm_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_frontGPIO.output(left_back,0)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,1)  #right_frontGPIO.output(right_back,0)   #right_backdef Back(speed):L_Motor.ChangeDutyCycle(speed)GPIO.output(left_front,0)   #left_frontGPIO.output(left_back,1)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,0)  #right_frontGPIO.output(right_back,1)   #right_backdef Left(speed):L_Motor.ChangeDutyCycle(speed)GPIO.output(left_front,0)   #left_frontGPIO.output(left_back,1)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,1)  #right_frontGPIO.output(right_back,0)   #right_backdef Right(speed):L_Motor.ChangeDutyCycle(speed)GPIO.output(left_front,1)   #left_frontGPIO.output(left_back,0)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,0)  #right_frontGPIO.output(right_back,1)   #right_backdef Stop():L_Motor.ChangeDutyCycle(0)GPIO.output(left_front,0)   #left_frontGPIO.output(left_back,0)    #left_backR_Motor.ChangeDutyCycle(0)GPIO.output(right_front,0)  #right_frontGPIO.output(right_back,0)   #right_back

三、舵机角度控制

def set_servo_angle(channel,angle):angle=4096*((angle*11)+500)/20000pwm_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 Processimg, contours = Image_Processing()
width, height = 160, 120camera = cv2.VideoCapture(0)camera.set(3,width) camera.set(4,height) 

1、打开摄像头

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

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

# Capture the framesret, frame = camera.read()

2、把图像转换为灰度图

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

3、 高斯滤波(去噪)

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

4、亮度增强

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

5、转换为二进制

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

6、闭运算处理

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

7、获取轮廓

#get contoursbinary_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 framesret, frame = camera.read()# Crop the imageimage = framecv2.imshow('frame',frame)# to graygray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow('gray',gray)# Gausi blurblur = cv2.GaussianBlur(gray,(5,5),0)#brightenblur = cv2.convertScaleAbs(blur, None, 1.5, 30)#to binaryret,binary = cv2.threshold(blur,150,255,cv2.THRESH_BINARY_INV)cv2.imshow('binary',binary)#Closekernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))close = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)cv2.imshow('close',close)#get contoursbinary_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 coordinatesx, 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 coordM = cv2.moments(contour)x = int(M['m10']/M['m00'])y = int(M['m01']/M['m00'])print(x, y) return x,yexcept:print 'no objects'return 0,0

返回最大轮廓的坐标:

六、运动

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

# 3 MoveMove(x,y)

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

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

2、向前走

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

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

3、向左转

物体在左边1/4区域。

#leftelif x < width/4:Left(50)

4、向右转

物体在右边1/4区域。

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

代码

def Move(x,y):global second#stopif x==0 and y==0:Stop()#go aheadelif width/4 <x and x<(width-width/4):Front(70)#leftelif x < width/4:Left(50)#Rightelif x > (width-width/4):Right(50)

总代码

#Object Tracking
import  RPi.GPIO as GPIO
import time
import Adafruit_PCA9685
import numpy as np
import cv2second = 0width, height = 160, 120
camera = cv2.VideoCapture(0)
camera.set(3,width)
camera.set(4,height) l_motor = 18
left_front   =  22
left_back   =  27r_motor = 23
right_front   = 25
right_back  =  24def Motor_Init():global L_Motor, R_MotorL_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_servopwm_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_frontGPIO.output(left_back,0)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,1)  #right_frontGPIO.output(right_back,0)   #right_backdef Back(speed):L_Motor.ChangeDutyCycle(speed)GPIO.output(left_front,0)   #left_frontGPIO.output(left_back,1)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,0)  #right_frontGPIO.output(right_back,1)   #right_backdef Left(speed):L_Motor.ChangeDutyCycle(speed)GPIO.output(left_front,0)   #left_frontGPIO.output(left_back,1)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,1)  #right_frontGPIO.output(right_back,0)   #right_backdef Right(speed):L_Motor.ChangeDutyCycle(speed)GPIO.output(left_front,1)   #left_frontGPIO.output(left_back,0)    #left_backR_Motor.ChangeDutyCycle(speed)GPIO.output(right_front,0)  #right_frontGPIO.output(right_back,1)   #right_backdef Stop():L_Motor.ChangeDutyCycle(0)GPIO.output(left_front,0)   #left_frontGPIO.output(left_back,0)    #left_backR_Motor.ChangeDutyCycle(0)GPIO.output(right_front,0)  #right_frontGPIO.output(right_back,0)   #right_backdef set_servo_angle(channel,angle):angle=4096*((angle*11)+500)/20000pwm_servo.set_pwm_freq(50)                #frequency==50Hz (servo)pwm_servo.set_pwm(channel,0,int(angle))def Image_Processing():# Capture the framesret, frame = camera.read()# Crop the imageimage = framecv2.imshow('frame',frame)# to graygray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow('gray',gray)# Gausi blurblur = cv2.GaussianBlur(gray,(5,5),0)#brightenblur = cv2.convertScaleAbs(blur, None, 1.5, 30)#to binaryret,binary = cv2.threshold(blur,150,255,cv2.THRESH_BINARY_INV)cv2.imshow('binary',binary)#Closekernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))close = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)cv2.imshow('close',close)#get contoursbinary_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 coordM = cv2.moments(contour)x = int(M['m10']/M['m00'])y = int(M['m01']/M['m00'])print(x, y) return x,yexcept:print 'no objects'return 0,0def Move(x,y):global second#stopif x==0 and y==0:Stop()#go aheadelif width/4 <x and x<(width-width/4):Front(70)#leftelif x < width/4:Left(50)#Rightelif 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 Processimg, contours = Image_Processing()# 2 get coordinatesx, y = Get_Coord(img, contours)# 3 MoveMove(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)相关推荐

  1. 树莓派视觉跟踪小车_树莓派智能小车结合摄像头opencv进行物体追踪

    在开发树莓派智能小车的路上已经走了一年多时间了,起初做了以下简单的远程控制和避障功能,后来慢慢加入黑线循迹以及语音识别,物体识别的功能.前段时间在刷新闻头条的时候,偶然看到一外国大牛做的树莓派目标追踪 ...

  2. 树莓派视觉小车 -- 小球追踪(颜色追踪)(OpenCV色彩空间HSV)

    目录 效果展示 基础理论(HSV) 为什么用HSV空间而不是RGB空间? HSV 1.Hue(色相) 2.Value(明度) 3.Saturation(饱和度) 一.初始化 滑动条初始化 1.创建回调 ...

  3. 树莓派视觉小车 -- OpenCV巡线(HSL色彩空间、PID)

    目录 试错 试错1:形态学处理 试错2:HSV色彩空间 基础理论 1.HSV与HSL色彩空间 2.PID调节 一.OpenCV图像处理 1.在HSL色彩空间下得到二值图 2. 对二值图形态学处理 3. ...

  4. 树莓派视觉小车 -- 人脸追踪(人脸识别、PID控制舵机运动)

    目录 效果展示 基础理论(人脸识别) 1.基于特征的算法 2.基于图像的算法 3.Haar特征 4.Adaboost级联决策器 API 基础理论(PID算法) 1.作用 应用场景 2.PID原理 1. ...

  5. 自动跟随小车c语言,基于OpenCV的智能小车运动轨迹跟踪方法研究

    摘要: 随着人工智能技术的快速发展,智能小车开发受到越来越多研究者的关注,也已经成为一个重要的研究方向,而解决智能小车在路径规划中行驶的运动故障重要手段是对其进行的视频监控,但是智能小车的视频监控只能 ...

  6. OpenCV学习笔记(十六)——CamShift研究 OpenCV学习笔记(十七)——运动分析和物体跟踪Video OpenCV学习笔记(十八)——图像的各种变换(cvtColor*+)imgproc

    OpenCV学习笔记(十六)--CamShift研究 CamShitf算法,即Continuously Apative Mean-Shift算法,基本思想就是对视频图像的多帧进行MeanShift运算 ...

  7. OpenCV4每日一练day3:运行OpenCV示例程序(物体跟踪)

    step1:准备好摄像头,或用电脑自带摄像头也可以.这里使用的是英特尔D435i. step2:找到OpenCV自带的物体跟踪demo--camshiftdemo.cpp,添加到VS2015源文件中 ...

  8. OpenCV 3 Tracking API目标跟踪学习笔记——定义、物体跟踪常用算法、demo

    今天开始接触目标跟踪 本文翻译自https://www.learnopencv.com/object-tracking-using-opencv-cpp-python/#opencv-tracking ...

  9. 使用流光法实现物体跟踪

    简介 本篇讲解使用opencv提供的流光法算法接口,实现物体跟踪.范例代码为参考修改tvl1_optical_flow.cpp实现. 具体实现 实现代码 <span class="co ...

最新文章

  1. Windows Server 2012 之配置AD DS
  2. Linux监控进程的iops,linux性能监控工具--Collectl
  3. ROS知识:ros和硬件的连接点---ROS-Control
  4. matlab 替换指定的元素
  5. 如何查看服务器文件进程,如何查看服务器上的所有进程
  6. Machine Learning--决策树(一)
  7. java微信公众号支付开发平台_Java微信公众平台开发之公众号支付(微信内H5调起支付)...
  8. HVM is required for this operation - Run Xen on Nested System
  9. 数学建模 员工指派问题 Lingo求解优化问题
  10. 软件项目需求开发过程实践之软件需求说明书
  11. 计算机启用远程桌面连接失败,开启局域网远程桌面连接不上怎么办
  12. BeanShell用法汇总
  13. 几何公差:GPS 2019 产品几何技术规范 (GDT)
  14. 文件搜素神器-everthing 快
  15. Jekins配置Publish over SSH详解
  16. 数据库和SpringBoot
  17. 1.10 新概念 have a cold/headache
  18. 服务器安装系统路径,裸金属服务器安装多路径软件
  19. 明朝经典战役\明朝挽救历史狂澜\于谦人生最高点\北京保卫战
  20. 从面试官的角度谈谈后端面试

热门文章

  1. Java进程和线程关系及区别
  2. JavaScript正则表达式之语法
  3. npm start 作用
  4. 改变mac中launchpad图标大小
  5. linux定时器(crontab)实例
  6. hdu2236 无题II 最大匹配 + 二分搜索
  7. Ruby: Ruby脚本在测试中的使用
  8. Ubuntu下安装和配置Apache2
  9. python nltk book_NLTK学习笔记(一):语言处理和Python
  10. 用什么擦地最干净脑筋急转弯_22个数学脑筋急转弯答案,你能全部做出来吗?...