Ros小车应用篇(三)——网络摄像头YOLOV3实现小车跟踪目标

YOLO小车跟踪

在这里插入图片描述
在这里插入图片描述

  • yolo跟踪代码:https://download.csdn.net/download/zhuchen88988/20175153?spm=1001.2014.3001.5501

  • 小车博客:https://editor.csdn.net/md/?articleId=118612242

  • YOLOv3模型采用opencv dnn方式导入神经网络权重,再使用opencv读取视频流并转换为标准block接口进行前向传播。最后输出结果列表中存在物体质心,物体大小,物体标签置信度等等,将数据提出再进行画框。如果想要追踪目标就在循环中,判断标签是否属于要找的那个标签。

  • 详细opencv实现yoloV3可以看https://www.bilibili.com/video/BV18B4y1c7r4?p=11

oepncv使用Yolo注意点

  • 由于使用树莓派motion推流的网络摄像头,python读取视频如果处理不及时会造成极大程度卡顿,延时。
    所以想要解决卡顿问题需要使用重新编译源码的opencv gpu版本,在pip以及anaconda中中下载的opencv是无法使用GPU的。想要使用GPU版本opencv必须 安装cuda以及cudnn,通过cmake +vs 编译出来。网上有很多教程,不过可能会失败,如果想要一次成功,注意opencv版本和vs的版本如果opencv源码版本比较新,如4以上。建议vs版本也要在2016以上,cuda和cudnn版本也要比较新。反之 opencv在3.2以下,建议vs版本也要在2016以下,cuda,cudnn版本也要与之对应来。这样成功率比较高。
  • cmake配置opencv源码时候会出现github连不上的问题,经过百度可以手动下载下来,修改本地文件,或者,修改下载url,在github后加个s。或者直接翻墙。均可以解决这个问题
  • 还有一种解决延时的方法,是开启python多线程,一个线程读取视频流,另一线程yolo识别。读取视频流的线程做缓冲区,如果,yolo识别的结果反馈很慢,就丢弃后面的视频帧,这样也可以解决一些卡顿问题,但是这样会造成识别偶尔出现没有识别到目标的现象。
  • yolov3模型有好几个版本,我使用320分辨率,分辨率越高的版本识别效果越好,但是处理速度越慢。yolov3有一个最低配版本为yolo-tiny,网上有人在树莓派上使用神经网络加速棒可以在本地运行yolov3-tiny网络,不过帧率不搞。本文使用的是yolov3-320版本,GPU opencv帧率稳定在30帧左右。

通讯协议控制小车

  • python使用struct.pack函数打包字节流,并且可以指定大小端。非常方便。通讯协议按照我之前的博客https://blog.csdn.net/zhuchen88988/article/details/118637714?spm=1001.2014.3001.5501
  • 控制通讯源代码都封装成类在ROS_Car目录文件下。在Struct.py中可以看到其用法
  • 字节流的CRC校验还是用的C语言,通过MinGW 64(python 也是64位)编译出.so动态库,使用加载动态库的方法调用C语言的函数库。详细可以百度python调用C语言。当然python也是有CRC16校验库的,也可以通过python库实现。

小车跟踪

  • 小车实现跟踪目标原理即为,将摄像头识别到的目标一直处于镜头中央。yolo3前向传播后的结果中有物体的质心,即使得质心在屏幕中央即可。
  • 由于小车不能在Y轴方向上改变摄像头位置,所以只需要改变摄像头X轴(即左右轮速改变摄像头),使得物体质心处于摄像头中央,这可以使用PID进行调节,具体公式如下:V=Kperr+Kderr_last(没有加入积分),err即为目标与摄像头正中央水平轴X差距,PID实现如下:
def PIDX_result(Cx,Kp,Kd,PID_outputs):
    Ox = 320 #中点X位置
    global Vl_dir
    global Vr_dir
    global err_last
    global Vx
    if Cx !=0:


        if (Cx-Ox)<0:
            print("偏左")
            #偏左,右轮前向,左轮反向(原地左转向)
            Vl_dir=0x02
            Vr_dir=0x01

        elif (Cx-Ox)>0:
            print("偏右")
            #偏右,左轮向后,前轮相反(原地右转向)
            Vl_dir=0x01
            Vr_dir=0x02

    else :
        print("CX无值")
        Cx=320
        Vl_dir = 0x00
        Vr_dir = 0x00

    err=Cx-Ox

    err_D=err-err_last
    Vx=abs(float(Kp*err +Kd*err_D))

    err_last = err
    print("Vl_dir:",Vl_dir)
    print("Vr_dir:", Vr_dir)

    PID_outputs[0]=Vl_dir
    PID_outputs[1]=Vr_dir
    PID_outputs[2]=Vx

    return PID_outputs

  • 同理如果为飞控的话,可以加上Y轴,达到完美的跟踪目标。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值