YOLOv7+双目实现三维跟踪(python)

32 篇文章 19 订阅
12 篇文章 8 订阅

相关链接
1. YOLOV5 + 双目测距(python)
2. YOLOV7 + 双目测距(python)
3. YOLOv5+双目实现三维跟踪(python)
3. 具体实现效果已在Bilibili发布,点击跳转

1. 目标跟踪

用yolov7实现跟踪步骤比较简单,去官网下载yolov7源码,然后下载跟踪模块相关代码,链接:https://download.csdn.net/download/qq_45077760/87712810
将下载的内容全部拖进yolov7-main文件夹里,把环境装好,然后运行代码 detect_or_track.py
此时如果不出问题就完成了普通检测
这里有几个常用知识需要注意的,我直接在以下代码作了注释

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default='yolov7.pt', help='model.pt path(s)')# 设置权重
    parser.add_argument('--source', type=str, default='street.mp4', help='source')  # file/folder, 0 for webcam  设置检测路径
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='display results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')#是否保存检测结果
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')  # 设置检测类别
    parser.add_argument('--no-trace', action='store_true', help='don`t trace model')  
    parser.add_argument('--track', action='store_true', help='run tracking')#是否跟踪
    parser.add_argument('--show-track', action='store_true', help='show tracked path')  #显示跟踪轨迹
    parser.add_argument('--show-fps', action='store_true', help='show fps')# 显示fps
    parser.add_argument('--thickness', type=int, default=2, help='bounding box and font size thickness')
    parser.add_argument('--seed', type=int, default=1, help='random seed to control bbox colors') #初始数字,直接改变目标方框颜色和序号
    parser.add_argument('--nobbox', action='store_true', help='don`t show bounding box')
    parser.add_argument('--nolabel', action='store_true', help='don`t show label')
    parser.add_argument('--unique-track-color', action='store_true', help='show each track in unique color') # # 每条轨迹不同颜色

也可以用终端运行命令python detect_or_track.py --weight yolov7.pt --no-trace --view-img --source 1.mp4

--show-fps #显示fps
--seed 2 #初始数字,直接改变目标方框颜色和序号
--track  #每个方框左上角有ID数字
--classes 0 1 # 只显示前两种类型 (总共80种在data/coco.yaml里)
--show-track #显示跟踪轨迹
--unique-track-color # 每条轨迹不同颜色
--nobbox
--nolabel
--nosave# 不保存,把上边那行删掉,会保存到XXX\yolov7\runs\detect\exp

在这里插入图片描述

2. 测距模块

2.1 测距原理

测距原理详见 双目三维测距(python)

2.2 添加测距

接下来调用测距代码到主代码 detect_or_track.py 文件中,先在代码开头导入库,添加

from stereo import stereoconfig
from stereo.stereo import stereo_40
from stereo.stereo import stereo_threading, MyThread
from yolov5.utils.plots import plot_one_box

我们需要将立体匹配等代码写进跟踪模块里,具体写法在我之前开源的 YOLOv5+双目测距(python) 这片文章里已经提及,这里就不再细讲,最后计算得到目标框的中心点坐标和距离对其进行显示,具体如下

for *xyxy, conf, cls in det:
	global diatance
    # to deep sort format
    x_c, y_c, bbox_w, bbox_h = xyxy_to_xywh(*xyxy)
    xywh_obj = [x_c, y_c, bbox_w, bbox_h]
    xywh_bboxs.append(xywh_obj)
    confs.append([conf.item()])

    if (0 < xyxy[2] < 1280):
            x_center = (xyxy[0] + xyxy[2]) / 2
            y_center = (xyxy[1] + xyxy[3]) / 2
            x_0 = int(x_center)
            y_0 = int(y_center)
            if (0 < x_0 < 1280):
                x1 = xyxy[0]
                x2 = xyxy[2]
                y1 = xyxy[1]
                y2 = xyxy[3]

                if (accel_frame % fps_set == 0):
                    t3 = time.time()  # stereo time end
                    thread.join()
                    points_3d = thread.get_result()
                   # gol.set_value('points_3d', points_3d)
                    t4 = time.time()  # stereo time end
                    print(f'{s}Stereo Done. ({t4 - t3:.3f}s)')
                a = points_3d[int(y_0), int(x_0), 0] / 1000
                b = points_3d[int(y_0), int(x_0), 1] / 1000
                c = points_3d[int(y_0), int(x_0), 2] / 1000
                distance = ((a**2+b**2+c**2)**0.5)

                if (distance != 0):  ## Add bbox to image
                    label = f'{names[int(cls)]} {conf:.2f} '
                    text_xy_0 = "*"
                    print('点 (%d, %d) 的 %s 距离左摄像头的相对距离为 %0.2f m' % (x_center, y_center, label, distance))
                    text_dis_avg = "dis:%0.2fm" % distance
                    cv2.rectangle(im0, (int(x1 + (x2 - x1)), int(y1)),(int(x1 + (x2 - x1) + 5 + 100), int(y1 + 12)), colors[int(cls)],-1)  # 画框存三维坐标
                    cv2.putText(im0, text_dis_avg, (int(x1 + (x2 - x1) + 5), int(y1 + 10)),cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 2)

也可以把 if (distance != 0) 及其后边的代码删除,直接把 points_3d 设置成全局变量,在 draw_boxes 里显示,具体如下

def draw_boxes(img, bbox, identities=None, categories=None, confidences = None, names=None, colors = None):
    global distance
    for i, box in enumerate(bbox):
        x1, y1, x2, y2 = [int(i) for i in box]
        tl = opt.thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness
        if (0 < x2 < 1280):
            cat = int(categories[i]) if categories is not None else 0
            id = int(identities[i]) if identities is not None else 0
            color = colors[cat]

            if not opt.nobbox:
                cv2.rectangle(img, (x1, y1), (x2, y2), color, tl)

            if not opt.nolabel:
                #label = str(id) + ":" + names[cat] if identities is not None else f'{names[cat]} {confidences[i]:.2f}'
                label = str(id) + ":"+ names[cat]+ "  "+"dis:"+str(distance)+"m" if identities is not None else  f'{names[cat]} {confidences[i]:.2f}'
                tf = max(tl - 1, 1)  # font thickness
                t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
                c2 = x1 + t_size[0], y1 - t_size[1] - 3
                cv2.rectangle(img, (x1, y1), c2, color, -1, cv2.LINE_AA)  # filled
                cv2.putText(img, label, (x1, y1 - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)

3. 细节修改(可忽略)

实时显示画面太大,我们对显示部分做了修改,这部分也可以不要,具体是把代码

if view_img:
      cv2.imshow(str(p), im0)
      cv2.waitKey(1)  # 1 millisecond

替换成

if view_img:
     cv2.namedWindow("Webcam", cv2.WINDOW_NORMAL)
     cv2.resizeWindow("Webcam", 1280, 720)
     cv2.moveWindow("Webcam", 0, 100)
     cv2.imshow("Webcam", im0)
     cv2.waitKey(1)

4. 实验效果

从实验效果可以看出来其实这里是存在一些问题的,虽然测距我只让他在左相机画面显示,但是跟踪的话两个相机画面同时进行了跟踪,估计是跟踪模块没有做改动,这一个细节后续也会去深入研究,大家如果有了解这一块如何修改的的也可以联系我


更多测距代码见博客主页源代码后续会开源…

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
<项目介绍> 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到94.5分,放心下载使用! 该资源适合计算机相关专业(如人工智能、通信工程、自动化、软件工程等)的在校学生、老师或者企业员工下载,适合小白学习或者实际项目借鉴参考! 当然也可作为毕业设计、课程设计、课程作业、项目初期立项演示等。如果基础还行,可以在此代码基础之上做改动以实现更多功能。 双目测距理论及其python运用 一、双目测距基本流程 Stereo Vision, 也叫双目立体视觉,它的研究可以帮助我们更好的理解人类的双眼是如何进行深度感知的。双目视觉在许多领域得到了应用,例如城市三维重建、3D模型构建(如kinect fusion)、视角合成、3D跟踪、机器人导航(自动驾驶)、人类运动捕捉(Microsoft Kinect)等等。双目测距也属于双目立体视觉的一个应用领域,双目测距的基本原理主要是三角测量原理,即通过视差来判定物体的远近。 那么总结起来,双目测距的大致流程就是: **双目标定 --> 立体校正(含消除畸变) --> 立体匹配 --> 视差计算 --> 深度计算(3D坐标)计算** linux下安装opencv-python: ```python pip install opencv-python ``` 二、相机畸变 光线经过相机的光学系统往往不能按照理想的情况投射到传感器上,也就是会产生所谓的畸变。畸变有两种情况:一种是由透镜形状引起的畸变称之为径向畸变。在针孔模型中,一条直线投影到像素平面上还是一条直线。可是,在实际拍摄的照片中,摄像机的透镜往往使得真实环境中的一条直线在图片中变成了曲线。越靠近图像的边缘,这种现象越明显。由于实际加工制作的透镜往往是中心对称的,这使得不规则的畸变通常径向对称。它们主要分为两大类,桶形畸变 和 枕形畸变(摘自《SLAM十四讲》)如图所示: <div align=center><img src="https://img-blog.csdnimg.cn/20190907184815326.PNG" width="324" height="100" /></div> 桶形畸变是由于图像放大率随着离光轴的距离增加而减小,而枕形畸变却恰好相反。 在这两种畸变中,穿过图像中心和光轴有交点的直线还能保持形状不变。
双目相机三维重建是一种利用双目摄像头获取的图像信息进行三维重建的技术。在Python中,可以使用OpenCV库来实现双目三维重建。下面是一个简的示例代码,演示了如何使用Python和OpenCV进行双目相机三维重建: ```python import cv2 import numpy as np # 读取左右相机的图像 left_image = cv2.imread('left_image.jpg') right_image = cv2.imread('right_image.jpg') # 进行立体校正 # 这里需要进行双目标定和立体校正的操作,具体步骤可以参考相关的教程或文档 # 进行立体匹配 # 这里可以使用OpenCV中的StereoBM或StereoSGBM算法进行立体匹配,具体步骤可以参考相关的教程或文档 # 计算视差图 # 这里可以使用立体匹配得到的结果来计算视差图,具体步骤可以参考相关的教程或文档 # 根据视差图计算深度图或三维坐标 # 这里可以使用视差图来计算深度图或三维坐标,具体步骤可以参考相关的教程或文档 # 显示结果 cv2.imshow('Left Image', left_image) cv2.imshow('Right Image', right_image) cv2.imshow('Disparity Map', disparity_map) cv2.imshow('Depth Map', depth_map) cv2.waitKey(0) cv2.destroyAllWindows() ``` 请注意,上述代码只是一个简单的示例,实际的双目相机三维重建过程可能涉及更多的步骤和参数调整。具体的实现方法和步骤可以根据你的需求和具体情况进行调整。如果你需要更详细的教程或文档,可以参考引用和引用中提供的链接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积极向上的mr.d

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值