前言
最近大家都在问,双目视觉和目标检测结合,看起来作为新手的大家不太会,这里我先用最简单的办法,教大家快速实现这个过程。(这里我以火灾检测为例,因为火灾数据比较简单)
一、双目相机标定
大家可以参考我之前的文章,标定双目相机,假设这里我们得到校正好的左图和右图了。
二、训练火灾目标检测
这里以yolov5 6.0 为例,其他算法的也可以。原理上都差不多。(这里讲解最简单的方法,原理大体上是对左图和右图分别检测,然后根据双目原理得到结果。)
首先GitHub下载yolov5,哪个版本都行,但是要和训练结果用同一个版本就可以了。
下载之后,就可以开始训练了,yolov5如何训练,网络上一搜一大堆这里就不赘述了。(假设这里已经得到train的训练结果)
我们只需要修改detect.py即可。
首先把要把左图和右图合成一张图,可以运行我下面的脚本。
from PIL import Image
# 读取左右两张图片
left_image = Image.open('left.png')
right_image = Image.open('right.png')
# 获取两张图片的宽度和高度
width, height = left_image.size
# 创建一张新的图片,宽度为两张图片的宽度之和,高度为其中一张图片的高度
merged_image = Image.new('RGB', (width * 2, height))
# 将左右两张图片合并到新的图片中
merged_image.paste(left_image, (0, 0))
merged_image.paste(right_image, (width, 0))
# 保存合并后的图片
merged_image.save('merged.png')
print('图片合并完成,保存为merged.png')
现在我们检测这张图片就可以得到两个目标了。
三、计算目标检测距离
根据双目视觉原理,z=bf/d,可以看我之前的文章相机标定和双目相机标定标定原理推导及效果展示。
这里最简单的方法就是两个检测框的中心点相减得到视差d,然后B基线和焦距f都在标定得到了,这样就可以得到距离了。
在yolov5中找到detect.py,找到得到检测结果的那部分代码。
这里*xyxy就是检测的坐标, conf置信度, cls类别。
for *xyxy, conf, cls in reversed(det):
我们只需要修改这里即可(这里我就按单目标简单修改了)。
D = []
for *xyxy, conf, cls in reversed(det):
x_d = (xyxy[0] + xyxy[2]) / 2
D.append(x_d)
if save_txt: # Write to file
xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
line = (cls, *xywh, conf) if opt.save_conf else (cls, *xywh) # label format
with open(txt_path + '.txt', 'a') as f:
f.write(('%g ' * len(line)).rstrip() % line + '\n')
if save_img or view_img: # Add bbox to image
label = f'{names[int(cls)]} {conf:.2f}'
plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
diffs = abs(D[1] - D[0])
distance = BF/diffs
print(“距离为”,distance)
总结
这里只想给大家介绍一下流程,关于后面检测没有仔细写,大家有什么问题可以留言讨论。
对于得到视差d,也可以用如何SGBM立体匹配,原理上差不多,还有关于使用SGBM推理时间比较久的问题,可以通过多线程,一个线程检测,一个线程匹配同步进行等等操作,关于检测框中心点关于多目标的问题,可以根据图片尺寸进行划分左图右图,然后根据邻域搜索等操作。后续大家催更比较多,可以给大家补充。