一.简介
本教程主要是使用YoloV5模型来实现对某一单一目标类型进行识别,并通过云台来实现对目标的追踪。由于本教程相关的项目目前正在参加比赛,所以不能透露出全部代码,请见谅!
注:本教程较为简洁,只提供代码逻辑,详细教程后续会发布(包含完整代码)
二.教程
1.设备
硬件需要树莓派5(所有支持IIC协议的Linux设备都可以),PCA9685板,USB摄像头,SG90S舵机两个,云台。(如图)
库的话需要YoloV5模型,adafruit_servokit库(控制舵机),numpy库,OpenCV库,torch库,time库。
2.教程
前两部分代码逻辑大致如下(以无人机举例):
首先便是导入“二”部分的所有库,之后创建一个class
class DroneTracker:
#........
#最后别忘了释放资源
if __name__ == "__main__":
tracker = DroneTracker() #这里你class里面是什么就写什么
try:
tracker.detect_and_track()
finally:
cv2.destroyAllWindows()
print("程序已结束,资源已释放。")
创建完了之后搞几个def
def __init__(self): #初始化舵机,PCA9685板是16通道的一块控制板
self.kit = ServoKit(channels=16)
self.Servo1 = self.kit.servo[0] # 控制水平旋转
self.Servo2 = self.kit.servo[1] # 控制垂直俯仰
#........
self.Servo1.angle = 90 # 初始化角度
self.Servo2.angle = 90
#........
这里主要是初始化舵机,设置初始化角度,一般设置90度,毕竟直接在中间也方便许多。同时我用的云台只需要2个舵机,就设置了两个舵机,当然你也可以搞16个(最多16个),全凭自己喜好哈doge
完了之后设置一下自己的模型
self.device = select_device('cpu') # 或者使用 'cuda' 如果有GPU
self.model = DetectMultiBackend('你自己模型的地址', device=self.device)
self.model.warmup((1, 3, 640, 640)) # 模型预热
记住别忘记改一下模型的地址哈,这里YoloV5我喜欢V5S,在Linux上面运行相对流畅
下一步就是怎么设置舵机的旋转了,话不多说,直接上这一部分的代码!
def adjust_servos(self, x_offset, y_offset):
"""根据偏移调整舵机角度"""
new_x_angle = max(1, min(180, self.Servo1.angle + x_offset))
new_y_angle = max(1, min(180, self.Servo2.angle + y_offset))
self.Servo1.angle = new_x_angle
self.Servo2.angle = new_y_angle
这里我是设定的根据目标距离图像中心的x,y差值来控制舵机的移动,在这段代码中是” x_offset和 y_offset“,后面也会有提到,这两个数值就是偏移距离,这样的话可以让舵机的移动更加”丝滑“!
好了,最重点的地方来了,就是怎么检测特定的单一目标并追踪呢?
在完成视频读取等一系列动作之后,之后便是特定种类的识别,这一段代码是这样的:
if self.model.names[int(cls)] == 'drone':
对,其实就是一个简单的if判断 ,将识别到的特定目标读取后,这时就有了以下代码
x_offset = -(center_x - screen_center_x) / frame_width * 10
y_offset = (center_y - screen_center_y) / frame_height * 10
self.adjust_servos(x_offset, y_offset)
这样前面舵机的偏移度数就有了 ,就会根据差值来计算偏移度数了,然后这一段完整代码等比赛结束后会向各位展示的,因为比较重要,几个项目都有(抱歉)
最后”show“以下,返回结束进程,整个代码就结束了!
cv2.imshow('Drone Tracking', frame)
if cv2.waitKey(1) == ord('q'): # 按'q'退出
break
三.总结
其实没展示的代码是重中之重,后续会更新的,敬请期待!