树莓派,opencv,Picamera2利用舵机云台追踪特定颜色对象

2023-12-12 10:44

本文主要是介绍树莓派,opencv,Picamera2利用舵机云台追踪特定颜色对象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、需要准备的硬件

  1. Raspiberry 4b
  2. 两个SG90 180度舵机(注意舵机的角度,最好是180度且带限位的,切勿选360度舵机)
  3. 二自由度舵机云台(如下图)
  4. Raspiberry CSI 摄像头
    组装后的效果:
    在这里插入图片描述

二、项目目标

追踪特定颜色的物体:
当物体移动时,摄像头通过控制两个伺服电机(分别是偏航和俯仰)把该物体放到视界的中心位置,我在这里追踪的是一支红色的铅笔。

三、具体步骤

3.1 获得被追踪对象的颜色参数

  1. 提前准备一张图片(如下图),可以直接用树莓派的CSI摄像头拍摄并保存,具体方法可以在我之前的文章里找到
    原始图片

  2. 利用下面的代码并通过调整滑块(Trackbar)获得红色铅笔的HSV颜色参数,为接下来的颜色追踪做准备

***color_detection.py***
import cv2
path='test_full.jpg'
cv2.namedWindow("TrackBar")def nothing(x):pass
#创建滑块控件
cv2.createTrackbar("Hue Min","TrackBar",0,179,nothing)
cv2.createTrackbar("Hue Max","TrackBar",179,179,nothing)
cv2.createTrackbar("Sat Min","TrackBar",0,255,nothing)
cv2.createTrackbar("Sat Max","TrackBar",255,255,nothing)
cv2.createTrackbar("Val Min","TrackBar",0,255,nothing)
cv2.createTrackbar("Val Max","TrackBar",255,255,nothing)while True:#读取目标图片image=cv2.imread(path)image=cv2.resize(image,(640,480))imgHSV=cv2.cvtColor(image,cv2.COLOR_BGR2HSV)hueLow=cv2.getTrackbarPos("Hue Min","TrackBar")hueHigh=cv2.getTrackbarPos("Hue Max","TrackBar")satLow=cv2.getTrackbarPos("Sat Min","TrackBar")satHigh=cv2.getTrackbarPos("Sat Max","TrackBar")valLow=cv2.getTrackbarPos("Val Min","TrackBar")valHigh=cv2.getTrackbarPos("Val Max","TrackBar")print(hueLow,hueHigh,satLow,satHigh,valLow,valHigh)#创建掩膜mask=cv2.inRange(imgHSV,(hueLow,satLow,valLow),(hueHigh,satHigh,valHigh))image=cv2.bitwise_and(image,image,mask=mask)#显示图像cv2.imshow('Origial',image)cv2.imshow('HSV',imgHSV)#按q键退出if cv2.waitKey(1)==ord('q'):break
cv2.destroyAllWindows() 
  1. 运行color_detection.py,并调整滑块(TrackBar)如下图,当然你的被追踪物体的颜色不同,参数也必然不同。
    滑块调整
    这时你会发现,红色铅笔被显示出来,其它部分被掩膜遮挡,记下Hue Min, Hui Max, Sat Min, Sat Max, Val Min, Val Max这六个数值在接下来的代码中会用到。
    在这里插入图片描述

3.2 目标追踪代码

  1. 输入color_detection.py里得到的六个参数到相应位置,注释里已经注明。
***color_tracking.py***
import cv2
from picamera2 import Picamera2
import time
import numpy as np
from servo import Servo
picam2 = Picamera2()#偏航伺服电机连接上GPIO19脚,俯仰伺服电机信号线连接到GPIO16脚上
pan=Servo(pin=19)
tilt=Servo(pin=16)panAngle=0
tiltAngle=0pan.set_angle(panAngle)
tilt.set_angle(tiltAngle)#初始化pi camera
dispW=1280
dispH=720
picam2.preview_configuration.main.size = (dispW,dispH)
picam2.preview_configuration.main.format = "RGB888"
picam2.preview_configuration.controls.FrameRate=30
picam2.preview_configuration.align()
picam2.configure("preview")
picam2.start()
fps=0
pos=(30,60)
font=cv2.FONT_HERSHEY_SIMPLEX
height=1.5
weight=3
myColor=(0,0,255)def nothing(x):passcv2.namedWindow('myTracker')
#输入color_detection.py里得到的六个参数到xxx位置,比如cv2.createTrackbar('Hue Low','myTracker',xxx,179,nothing)
cv2.createTrackbar('Hue Low','myTracker',56,179,nothing)
cv2.createTrackbar('Hue High','myTracker',179,179,nothing)
cv2.createTrackbar('Sat Low','myTracker',165,255,nothing)
cv2.createTrackbar('Sat High','myTracker',255,255,nothing)
cv2.createTrackbar('Val Low','myTracker',77,255,nothing)
cv2.createTrackbar('Val High','myTracker',255,255,nothing)while True:tStart=time.time()#获取取摄像头图片frame= picam2.capture_array()frame=cv2.flip(frame,1)frameHSV=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)cv2.putText(frame,str(int(fps))+' FPS',pos,font,height,myColor,weight)hueLow=cv2.getTrackbarPos('Hue Low','myTracker')satLow=cv2.getTrackbarPos('Sat Low','myTracker')valLow=cv2.getTrackbarPos('Val Low','myTracker')hueHigh=cv2.getTrackbarPos('Hue High','myTracker')satHigh=cv2.getTrackbarPos('Sat High','myTracker')valHigh=cv2.getTrackbarPos('Val High','myTracker')lowerBound=np.array([hueLow,satLow,valLow])upperBound=np.array([hueHigh,satHigh,valHigh])myMask=cv2.inRange(frameHSV,lowerBound,upperBound)myMaskSmall=cv2.resize(myMask,(int(dispW/2),int(dispH/2)))myObject=cv2.bitwise_and(frame,frame, mask=myMask)myObjectSmall=cv2.resize(myObject,(int(dispW/2),int(dispH/2)))contours,junk=cv2.findContours(myMask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)if len(contours)>0:contours=sorted(contours,key=lambda x:cv2.contourArea(x),reverse=True)#cv2.drawContours(frame,contours,-1,(255,0,0),3)contour=contours[0]x,y,w,h=cv2.boundingRect(contour)cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),3)#偏航电机纠偏X轴方向上的偏差,大于30度,偏航角度减小,小于-30度,偏航角度增加errorX=dispW/2-(x+w/2)if errorX>30:panAngle=panAngle-1if panAngle<-90:panAngle=-90pan.set_angle(panAngle)if errorX<-30:panAngle=panAngle+1if panAngle>90:panAngle=90pan.set_angle(panAngle)#俯仰电机纠偏Y轴方向上的偏差,大于30度,俯仰角度减小,小于-30度,俯仰角度增加errorY=dispH/2-(y+h/2)if errorY>30:tiltAngle=tiltAngle-1if tiltAngle<-90:tiltAngle=-90tilt.set_angle(tiltAngle)if errorY<-30:tiltAngle=tiltAngle+1if tiltAngle>90:tiltAngle=90tilt.set_angle(tiltAngle)cv2.imshow('Camera',frame)cv2.imshow('Mask',myMaskSmall)cv2.imshow('My Object',myObjectSmall)#按q键退出if cv2.waitKey(1)==ord('q'):pan.stop()tilt.stop()picam2.stop()breaktEnd=time.time()loopTime=tEnd-tStartfps=.9*fps + .1*(1/loopTime)
cv2.destroyAllWindows()
  1. 上述代码中的from servo import Servo导入servo,这个库是没有的,我们要手动创建这个库,在object_tracking.py所在的目录下新建servo.py文件,复制下面的代码到文件中
#!/usr/bin/env python3
import pigpio
from time import sleep
# Start the pigpiod daemon
import subprocess
result = None
status = 1
for x in range(3):p = subprocess.Popen('sudo pigpiod', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)result = p.stdout.read().decode('utf-8')status = p.poll()if status == 0:breaksleep(0.2)
if status != 0:print(status, result)
'''
> Use the DMA PWM of the pigpio library to drive the servo
> Map the servo angle (0 ~ 180 degree) to (-90 ~ 90 degree)'''class Servo():MAX_PW = 1250  # 0.5/20*100MIN_PW = 250 # 2.5/20*100_freq = 50 # 50 Hz, 20msdef __init__(self, pin, min_angle=-90, max_angle=90):self.pi = pigpio.pi()self.pin = pin self.pi.set_PWM_frequency(self.pin, self._freq)self.pi.set_PWM_range(self.pin, 10000)      self.angle = 0self.max_angle = max_angleself.min_angle = min_angleself.pi.set_PWM_dutycycle(self.pin, 0)def set_angle(self, angle):if angle > self.max_angle:angle = self.max_angleelif angle < self.min_angle:angle = self.min_angleself.angle = angleduty = self.map(angle, -90, 90, 250, 1250)self.pi.set_PWM_dutycycle(self.pin, duty)def get_angle(self):return self.angledef stop(self):self.pi.set_PWM_dutycycle(self.pin, 0)self.pi.stop()# will be called automatically when the object is deleted# def __del__(self):#     passdef map(self, x, in_min, in_max, out_min, out_max):return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_minif __name__ =='__main__':from vilib import Vilib# Vilib.camera_start(vflip=True,hflip=True) # Vilib.display(local=True,web=True)pan = Servo(pin=13, max_angle=90, min_angle=-90)tilt = Servo(pin=12, max_angle=30, min_angle=-90)panAngle = 0tiltAngle = 0pan.set_angle(panAngle)tilt.set_angle(tiltAngle)sleep(1)while True:for angle in range(0, 90, 1):pan.set_angle(angle)tilt.set_angle(angle)sleep(.01)sleep(.5)for angle in range(90, -90, -1):pan.set_angle(angle)tilt.set_angle(angle)sleep(.01)sleep(.5)for angle in range(-90, 0, 1):pan.set_angle(angle)tilt.set_angle(angle)sleep(.01)sleep(.5)
  1. 运行object_tracking.py,移动红色铅笔,摄像头就会自动追踪该对象
    在这里插入图片描述

这篇关于树莓派,opencv,Picamera2利用舵机云台追踪特定颜色对象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/484322

相关文章

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

使用Python实现获取屏幕像素颜色值

《使用Python实现获取屏幕像素颜色值》这篇文章主要为大家详细介绍了如何使用Python实现获取屏幕像素颜色值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、一个小工具,按住F10键,颜色值会跟着显示。完整代码import tkinter as tkimport pyau

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以