首页IT科技Yolov5目标检测 + Tensor RT加速(基于yolov5的目标检测和单目测距)

Yolov5目标检测 + Tensor RT加速(基于yolov5的目标检测和单目测距)

时间2025-06-21 03:26:11分类IT科技浏览4882
导读:废话在前头   因为我的毕业设计就是搞目标检测这一块的,前段时间好不容易实现了yolov5的目标检测,后来还需要实现目标测距,于是在B站和博客里不断摸索,效果很不理想,知识点零散,幸运的是最终琢磨懂了代码和原理。...

废话在前头

  因为我的毕业设计就是搞目标检测这一块的              ,前段时间好不容易实现了yolov5的目标检测                     ,后来还需要实现目标测距       ,于是在B站和博客里不断摸索              ,效果很不理想                     ,知识点零散       ,幸运的是最终琢磨懂了代码和原理              。全文通俗易懂                     。

正文开始

1              、最终目的

  实现目标检测跟踪和目标测距 !

2                     、实现过程

2.1 实现的前提

  前提是你要会用yolov5实现目标检测       ,我是跟着一位博主学做出来的——目标检测—教你利用yolov5训练自己的目标检测模型        。重点是在B站里也有他做的 保姆级视频                     ,本文着重讲解单目测距              。 实现了yolov5检测之后直接去我的gitee上下载我的测距项目: yolov5-main                     。下载并解压项目到PyCharm中              ,配置上运行yolov5的环境       ,然后跑一遍detect.py                     ,看看我的案例效果              ,成功运行后再跟着教程慢慢搞       。

2.2 知识点简要梳理

  因为条件的限制,我没有选择双目测距来研究                     ,其实单目和双目各有优缺点       。它们的原理网上搜也是一大把                     ,本文直接跳过原理讲解,我们来讲公式:

D = (F*W)/P

其中D是目标到摄像机的距离(最终要推测的距离), F是摄像机焦距(根据下面教程来调试自己的镜头焦距), W是目标的宽度或者高度(看情况来定              ,行人检测一般以人的身高为基准), P是指目标在图像中所占据的x方向像素(宽)或者y方向像素(高)(程序来计算)                     。 2.3 单目测距代码

  先来看看核心代码

foc = 1810.0 # 镜头焦距 real_hight_person = 64.96 # 行人高度,注意单位是英寸 # 自定义函数                     ,单目测距 def detect_distance_person(h): dis_inch = (real_hight_person * foc) / (h - 2) dis_cm = dis_inch * 2.54 dis_cm = int(dis_cm) dis_m = dis_cm/100 return dis_m

简单理解一下代码       ,定好焦距(通过下一步调试可得)和行人高度(这里定一般人的身高              ,我定165cm                     ,可以调       ,单位为英寸)       ,然后在调用这个测距函数的时候                     ,把行人所占据的像素高度h(其实就是利用到方框的像素高度)传进来              ,这个函数首先会根据公式计算出单位为英尺的距离       ,然后转换                     ,最终得到单位为米的距离              。

2.4 调试焦距

网上有说相机标定这个操作              ,我没有深入研究,貌似可以矫正图片                     ,减小误差       。我是直接跳过这个操作                     ,影响不大                     。

下面讲一下怎么调试焦距,我用的是手机摄像头              。 先是准备一张A4纸              ,横放在地板上或者别的东西上面                     ,要纯色为背景; 用卷尺量出60cm的高度       ,或者用棍子画出60cm的高度              ,将手机打开录像                     ,横拍       ,这个时候就不要放大镜头了       ,垂直方正的将A4纸录十几秒的视频                     ,拍到的A4纸尽量不能歪; 将视频放到项目的test目录里              ,在detect_A4.py的第13行代码换上这个视频。运行detect_A4.py       ,首先看一下有没有绿色的矩形出现并包裹住A4纸                     ,如果没有或者有但是明显包裹不紧的话就调节25行代码的阈值              ,反复尝试,直到矩形出现并包裹紧A4纸                     。这个时候可以看到图像左上角有数值                     ,这个就是A4纸到镜头的推测距离                     ,我们需要通过调节foc焦距参数,让左上角这个数值接近60cm              ,最终的foc焦距就是你这个视频的焦距了                     ,往后检测视频就用这个焦距       ,而且检测的视频都是用这个焦距拍出来的                     。 2.5 拿到焦距就可以做目标测距了 2.5.1 讲一下总体思路

这个时候公式 D = (F*W)/P 的三个参数已经知道了F和W两个              ,这个P在下面2.的(4)里可以被计算出来。

我在utils目录下定义了一个distance.py, 它的功能就是测距                     ,我在里边定义了两个测距模型       ,一个是测人的       ,一个是测车的                     ,这个时候先把之前调试好的焦距写在foc参数里              ,行人和车的高度只是大概数值       ,单位为英寸                     ,自己可以改

; 然后来到根目录下的detect.py              ,这个文件我在基础上做了修改,讲一下改了哪些              。

(1)第60行定义了一个函数                     ,以1200为宽的比例更改显示图像的大小                     ,因为原本的这个yolov5项目是按原图像显示的,按我的焦距拍出来的视频会撑爆整个屏幕              ,所以要缩小显示                     ,这个函数会在150行显示的时候被调用; # 改变显示图片大小(自定义函数) def cv_show(p, im0): height, width = im0.shape[:2] a = 1200 / width # 宽为1200       ,计算比例 size = (1200, int(height * a)) img_resize = cv2.resize(im0, size, interpolation=cv2.INTER_AREA) cv2.imshow(p, img_resize) cv2.waitKey(1) # 1 millisecond

(2)116行做一个判断              ,置信度低的就不要显示了                     ,有时候地上一个图案都能被识别成人       ,用官方权重来检测       ,检测到的东西几乎都会被框上                     ,这样会很杂              ,我们可以根据需求选择我们想框的东西       ,像我一样在118行和131行各做了一个判断                     ,分别是判断是不是人和车              ,是的话就框出来并做相应处理,128行调用的plot_one_box()就是画框的函数;

if conf2 > 0.4: # 置信度小于0.4时不显示 # person                     ,显示person标签的框                     ,并单独做person的测距 if names[int(cls)] == person: plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3, name=names[int(cls)]) # 画框函数

(4)这个函数在utils里的polts.py里,我们来到polts.py里的59行              ,我给这个函数添加了一个参数name                     ,在画框的时候函数会根据name是人还是车进行相应的测距函数调用(68行和70行       ,参数h是目标的高度              ,63~65行通过方框坐标计算得出)                     ,所调用的测距函数也就是前面我定义好的distance.py里边的                     。然后71行就是在原本的方框标签上追加我们测距得到的距离数据;

def plot_one_box(x, img, color=None, label=None, line_thickness=3, name=None): c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3])) # 传过来的x包含有框的两个对角坐标 # w = int(x[2]) - int(x[0]) # 框的宽 h = int(x[3]) - int(x[1]) # 框的高 dis_m = 1.00 if name == person: # 根据标签名称调用不同函数计算距离 dis_m = detect_distance_person(h) elif name == car: dis_m = detect_distance_car(h) label += f {dis_m}m # 在标签后追加距离

(5)这点不是很重要       ,detect.py189行       ,是否保存检测结果到runs/detect目录下                     ,我这里关闭了              ,省储存       ,这点根据需求来改                     ,需要保存就把它改成store_true              ,然后在runs/detect目录下最后一个exp里找,因为每运行一次detect.py都会生成一个exp文件                     ,最后一次运行结果自然保存在最后一个exp里;

# store_true为保存视频或者图片                     ,路径为runs/detect parser.add_argument(--nosave, action=store_false, help=do not save images/videos) 总结就是,基于yolov5的检测              ,调用我们定义的测距函数                     ,拿到检测距离之后       ,把距离追加到方框的标签后面       。 2.5.1 实测自己的视频 自己用拍摄A4纸的方法              ,到路边横屏拍摄视频                     ,相机到腰的位置       ,拍点人或者车       ,注意不能改变焦距来拍                     ,用拍摄A4纸的状态来拍              。要问为什么不能竖屏拍              ,我只能说       ,我竖屏拍了视频传到项目里运行                     ,显示的图像会上下颠倒              ,不懂是什么原因; 拍好视频后,把视频传电脑里                     ,复制到项目data/videos目录下                     ,重命名一下,其实放哪里都无所谓              ,等会路径写对就好                     。 来到detect.py的181行                     ,更改数据源       ,改成刚刚那个视频的路径       。 见证奇迹的时刻到了              ,运行detect.py                     ,看看效果       。

3       、后语

  小学弟我才学疏浅       ,非计算机科班出身       ,对编程感兴趣                     ,自学Java出身              ,因为毕业设计意外选到人工智能的课题       ,所以临时自学Python                     ,然后慢慢接触人工智能                     。

  本文章虽然通俗易懂              ,但是缺乏专业术语              。

  代码中能看到的中文注释我建议简单理解一遍       。

  若有不足,望大佬指教!

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
python中类和对象的关系(python中类与对象之间关系)