从零构建YOLOv5+RealSense深度感知模型:实战数据集制作与测距应用

发布时间:2026/7/7 19:58:56

从零构建YOLOv5+RealSense深度感知模型:实战数据集制作与测距应用 1. 环境准备与工具安装第一次接触YOLOv5和RealSense的组合时我花了两天时间才把环境搭好。现在回想起来其实只要按步骤来半小时就能搞定。首先需要准备一台性能还行的电脑建议至少GTX 1660以上的显卡因为训练模型时CUDA加速真的很重要。安装Python环境时我强烈推荐使用Anaconda创建虚拟环境。这样可以避免各种依赖冲突。我常用的命令是conda create -n yolov5 python3.8 conda activate yolov5接下来安装PyTorch这里有个小技巧先去PyTorch官网用他们的配置生成器获取安装命令。我实测过直接用pip安装的版本有时CUDA支持会有问题。安装完记得验证一下CUDA是否可用import torch print(torch.cuda.is_available()) # 应该返回TrueRealSense SDK的安装稍微麻烦些。在Windows上可以直接用Intel提供的安装包Linux下则需要从源码编译。我遇到过最坑的问题是USB3.0接口识别如果相机老是断开连接试试换根质量好的USB线。2. 数据采集实战技巧用RealSense采集数据时很多人会忽略深度信息的校准。我发现最佳做法是先让相机预热5分钟等深度传感器稳定后再开始采集。采集环境的光线也很关键强光直射会导致深度图出现大量噪点。这段Python代码可以同时保存彩色图和深度图import pyrealsense2 as rs import numpy as np import cv2 pipeline rs.pipeline() config rs.config() config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) pipeline.start(config) try: for i in range(100): # 采集100张 frames pipeline.wait_for_frames() color_frame frames.get_color_frame() depth_frame frames.get_depth_frame() if not color_frame or not depth_frame: continue color_image np.asanyarray(color_frame.get_data()) depth_image np.asanyarray(depth_frame.get_data()) cv2.imwrite(fcolor_{i}.jpg, color_image) np.save(fdepth_{i}.npy, depth_image) # 深度图建议保存为npy格式 finally: pipeline.stop()采集时要注意目标物体的多样性包括不同角度、距离和光照条件。我建议每个类别至少采集200张以上太少会导致模型泛化能力差。3. 数据标注的坑与技巧LabelImg虽然简单易用但在处理大量数据时效率太低。我后来改用CVATComputer Vision Annotation Tool它支持多人协作标注还能直接导出YOLO格式。不过新手还是建议先用LabelImg熟悉标注流程。标注时有几个容易出错的地方边界框不要贴得太紧留2-3个像素的余量遮挡超过15%的物体要标记truncated属性相似物体在不同尺度下要分别标注标注完成后记得检查XML文件中的尺寸是否一致。我遇到过因为标注时缩放窗口导致坐标错误的情况可以用这个脚本批量检查import xml.etree.ElementTree as ET import os for xml_file in os.listdir(annotations): tree ET.parse(fannotations/{xml_file}) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) assert width 640 and height 480, f{xml_file}尺寸错误4. 模型训练与调优准备好数据后创建YOLOv5需要的yaml配置文件。这里有个细节很多人忽略类别名称的顺序很重要必须和标注时保持一致。我的mydata.yaml通常长这样train: ../mytrain/images/train/ val: ../mytrain/images/val/ nc: 3 # 类别数 names: [person, car, bottle] # 按字母顺序排列更方便管理开始训练前建议先用小批量数据测试流程是否通畅python train.py --img 640 --batch 16 --epochs 3 --data mydata.yaml --weights yolov5s.pt训练过程中要重点关注这几个指标mAP0.5高于0.8说明模型不错Precision和Recall的平衡损失函数的下降曲线如果出现过拟合可以尝试增加数据增强参数减小模型尺寸换成yolov5n添加Dropout层5. 深度信息融合实战将YOLOv5的检测结果与RealSense的深度图结合时坐标转换是关键。RealSense返回的深度值是毫米为单位的需要转换为米depth_value depth_frame.get_distance(x, y) # 获取的是米为单位为了提高测距精度我开发了一个多点采样取中值的算法def get_robust_distance(depth_frame, bbox, sample_points20): 通过多采样提高深度测量精度 x_center (bbox[0] bbox[2]) // 2 y_center (bbox[1] bbox[3]) // 2 width bbox[2] - bbox[0] distances [] for _ in range(sample_points): # 在目标区域内随机采样 x random.randint(int(x_center - width/4), int(x_center width/4)) y random.randint(int(y_center - width/4), int(y_center width/4)) dist depth_frame.get_distance(x, y) if 0 dist 10: # 过滤异常值 distances.append(dist) if not distances: return None # 取中间80%的数据的平均值 distances sorted(distances) trim int(len(distances) * 0.1) return sum(distances[trim:-trim]) / len(distances[trim:-trim])6. 性能优化技巧在实际部署时我发现有几点可以显著提升性能异步处理将图像采集、目标检测和深度计算放在不同线程from threading import Thread import queue image_queue queue.Queue(maxsize1) result_queue queue.Queue(maxsize1) def capture_thread(): while True: frames pipeline.wait_for_frames() color_frame frames.get_color_frame() image_queue.put(np.asanyarray(color_frame.get_data())) def detection_thread(): while True: img image_queue.get() # 执行检测... result_queue.put(results) Thread(targetcapture_thread, daemonTrue).start() Thread(targetdetection_thread, daemonTrue).start()模型量化将模型转为FP16或INT8格式速度可提升2-3倍python export.py --weights best.pt --include onnx --halfROI处理只对检测到的目标区域计算深度减少计算量7. 常见问题解决方案在项目开发过程中我踩过不少坑这里分享几个典型问题的解决方法问题1RealSense深度图与彩色图对齐不准解决方法使用align_to_color对齐align rs.align(rs.stream.color) frames align.process(frames)问题2YOLOv5检测框抖动严重解决方法添加简单的跟踪算法from collections import deque class SimpleTracker: def __init__(self, max_len5): self.history deque(maxlenmax_len) def update(self, bbox): self.history.append(bbox) return np.mean(self.history, axis0)问题3远距离测距不准解决方法根据距离动态调整采样区域大小def get_dynamic_sample_size(distance): base_size 0.2 # 20%的bbox大小 scale min(max(distance / 5.0, 0.5), 2.0) # 限制在0.5-2倍之间 return base_size * scale最后要提醒的是实时显示时用OpenCV的imshow性能很差可以考虑用PyQt或者Web前端来展示结果。我在一个项目中将检测结果通过WebSocket发送到网页端显示帧率提升了近3倍。

相关新闻