拓冰建站拓冰建站
首页 / 资讯中心 / 正文

YOLOv5+D435i实现双目标毫米级三维距离测量

简介本资源是一套基于YOLOv5与Intel RealSense D435i深度相机实现的物体间三维距离测量完整开发方案面向本科毕业设计、课程设计及期末大作业学生尤其适合计算机视觉与嵌入式感知方向的初学者与进阶学习者。方案涵盖从目标检测、深度图对齐、三维坐标计算到距离可视化全流程代码含详尽中文注释部署简易开箱即用。压缩包共2000个文件主体为1065个Python源码含模型训练/推理/标定/测距核心逻辑、605个编译后pyc文件、54个配置yaml及39个C/C底层扩展文件如fortranobject.c、cpu_avx512系列等体现算法与硬件加速协同设计整体大小148.37MB。已有245人学习下载提供高分项目全链路支撑——包括导师认可的98分毕设文档结构、D435i标定实操说明、YOLOv5轻量化适配细节、多物体三维坐标解算逻辑及典型场景测试结果分析助力快速复现与二次开发。1. 不用激光雷达仅靠YOLOv5D435i就能算出两个物体间的毫米级三维距离你手头只有一台Intel RealSense D435i和一台普通笔记本没有双目相机标定板、没有IMU辅助、也没有ROS环境——但你需要在毕业设计里实现「两个杯子之间相距多少厘米」这种带空间语义的测量任务。这不是简单的单点深度值读取而是要从YOLOv5检测框出发结合D435i的深度图与RGB对齐关系精确提取两个目标中心点在世界坐标系下的三维坐标再计算欧氏距离。这套方案绕开了SLAM建图、点云配准等重型流程实测误差稳定控制在±8mm以内1m内且部署后启动即用python main.py --target-class cup --min-conf 0.63秒内输出[cup_0] ↔ [cup_1]: 237.4 mm。它专为课程设计、期末大作业和本科毕设优化代码全注释、依赖精简仅torch opencv pyrealsense2、所有坐标变换均有数学推导支撑连内参矩阵如何从D435i固件中解析都写进了calibration_utils.py的docstring。如果你正被“三维距离”这个需求卡在开题阶段这项目就是可直接复现的最小可行闭环。2. YOLOv5检测结果到三维坐标的映射原理与坐标系对齐关键路径2.1 为什么不能直接用YOLOv5的bbox中心像素查深度值YOLOv5输出的是归一化坐标x_center, y_center, width, height而D435i的深度图是原始分辨率如640×480下的16位整型数组。若直接将归一化中心点乘以图像宽高得到像素坐标再查深度图会因以下三个问题导致结果漂移畸变未校正D435i出厂自带鱼眼畸变RGB和深度传感器物理位置不同需分别校正对齐未完成RGB图与深度图默认不同步、不同分辨率、不同视角必须调用rs.align(rs.stream.color)强制对齐尺度未统一深度图单位是毫米但YOLOv5训练时输入尺寸为640×640而D435i实际采集分辨率为640×480缩放比例不一致。提示项目中inference.py第47行明确调用align.process(frames)这是整个三维距离计算的前提。漏掉这一步后续所有坐标转换都是空中楼阁。2.2 D435i坐标系定义与YOLOv5检测框的坐标桥接RealSense SDK定义了三个关键坐标系Depth Camera Coordinate System原点在深度传感器光学中心Z轴指向镜头外X向右、Y向下右手系Color Camera Coordinate System原点在RGB传感器光学中心Z轴指向镜头外World Coordinate System用户自定义本项目以深度相机光心为原点Z轴为测量基准方向。YOLOv5检测框的中心点(x_px, y_px)在对齐后的RGB图像上需经三步映射到世界坐标系像素→归一化平面坐标利用D435i内参矩阵intrinsics可通过profile.get_stream(rs.stream.depth).as_video_stream_profile().get_intrinsics()获取# intrinsics: {fx: 615.32, fy: 615.19, ppx: 317.2, ppy: 235.1} x_norm (x_px - intrinsics.ppx) / intrinsics.fx y_norm (y_px - intrinsics.ppy) / intrinsics.fy此步将像素坐标转为以焦距为单位的归一化平面坐标。归一化平面→相机坐标系深度值z_mm单位毫米由对齐后的深度图在(x_px, y_px)处读取depth_frame aligned_depth_frame.get_distance(int(x_px), int(y_px)) # 返回米制浮点数 z_m depth_frame # 注意get_distance返回单位为米非毫米 x_m x_norm * z_m y_m y_norm * z_m此时(x_m, y_m, z_m)即为目标中心在深度相机坐标系下的三维坐标单位米。相机坐标系→世界坐标系本项目默认世界坐标系与深度相机坐标系重合即无外参旋转/平移故无需额外变换。若需多相机协同或机械臂抓取则需通过rs.extrinsics加载外参矩阵。2.3 实际代码中的坐标转换封装与防错机制项目在utils/coordinate_transform.py中封装了上述流程并加入三重防护深度值有效性检查if depth_mm 100 or depth_mm 10000:过滤无效深度10cm为近场噪声10m为超量程像素越界保护x_px np.clip(int(x_px), 0, depth_width-1)防止YOLOv5 bbox超出对齐后图像边界亚像素插值对深度图使用双线性插值cv2.resize(depth_image, (640,480), interpolationcv2.INTER_LINEAR)提升中心点定位精度。# utils/coordinate_transform.py 第89行 def pixel_to_world(x_px: float, y_px: float, depth_frame: rs.frame, intrinsics: rs.intrinsics) - Optional[np.ndarray]: 将RGB对齐图像上的像素坐标转换为世界坐标单位米 :param x_px: 归一化前的原始像素横坐标已对齐 :param y_px: 归一化前的原始像素纵坐标已对齐 :param depth_frame: 对齐后的深度帧rs.frame类型 :param intrinsics: 深度流内参rs.intrinsics :return: shape(3,) 的numpy数组 [x, y, z]失败返回None # 越界保护 w, h depth_frame.get_width(), depth_frame.get_height() x_clipped max(0, min(w-1, int(x_px))) y_clipped max(0, min(h-1, int(y_px))) # 获取深度值单位米 depth_m depth_frame.as_depth_frame().get_distance(x_clipped, y_clipped) if not (0.1 depth_m 10.0): # 10cm ~ 10m有效区间 return None # 归一化平面坐标 x_norm (x_clipped - intrinsics.ppx) / intrinsics.fx y_norm (y_clipped - intrinsics.ppy) / intrinsics.fy # 相机坐标系 x_cam x_norm * depth_m y_cam y_norm * depth_m z_cam depth_m return np.array([x_cam, y_cam, z_cam])该函数被main.py中calculate_3d_distance()直接调用每次检测到两个以上目标即批量处理。注意depth_frame.as_depth_frame()是必需的类型转换否则get_distance()会报错。3. 双目标三维距离计算的完整流水线与参数调优策略3.1 从YOLOv5推理到距离输出的端到端流程整个系统运行逻辑如下图所示文字描述D435i硬件采集 → RGBDepth双流 → 对齐rs.align → YOLOv5推理RGB图 ↓ 检测框列表 → 筛选目标类别--target-class → 对每个框中心点执行pixel_to_world() ↓ 生成三维坐标列表 → 两两组合计算欧氏距离 → 按距离升序排序 → 输出最短/最长/指定序号对核心入口main.py中run_inference()函数控制主循环关键参数通过argparse传入参数类型默认值说明--target-classstrperson指定待测目标类别支持多个用逗号分隔如cup,bottle--min-conffloat0.5YOLOv5置信度阈值低于此值的检测框被丢弃--max-distfloat3.0世界坐标系下两点最大允许距离单位米过滤远场误检--distance-modestrshortest可选shortest/longest/all控制输出哪组距离3.2 YOLOv5模型轻量化与D435i实时性适配原始YOLOv5s在CPU上推理速度约3.2 FPSIntel i5-1135G7无法满足实时测距需求。本项目采用三项针对性优化输入尺寸压缩将imgsz640改为imgsz320推理速度提升至8.7 FPS精度损失2%mAP0.5后处理加速禁用non_max_suppression的冗余IOU计算改用cv2.dnn.NMSBoxesOpenCV内置C实现深度图缓存复用每帧只调用一次aligned_depth_frame align.process(frames)避免重复对齐开销。# models/common.py 第124行修改后的NMS调用 boxes np.array([[x1, y1, x2-x1, y2-y1] for x1,y1,x2,y2 in xyxy_list]) scores np.array(conf_list) indices cv2.dnn.NMSBoxes(boxes, scores, score_threshold0.5, nms_threshold0.4) valid_detections [dets[i] for i in indices.flatten()] # indices为ndarray需flatten()注意cv2.dnn.NMSBoxes返回的是ndarray而非Python list必须调用.flatten()才能索引。项目requirements.txt已锁定opencv-python4.8.1.78低版本可能无此API。3.3 双目标匹配策略与距离稳定性增强当画面中存在多个同类目标如3个杯子时系统需确定哪两个构成“待测对象”。本项目提供三种模式shortest计算所有组合距离返回最小值对应的一对适合测最近障碍物longest返回最大值对应的一对适合测跨度all输出全部组合及距离调试用。为提升稳定性增加帧间一致性滤波连续5帧内若同一目标ID基于中心点欧氏距离跟踪的三维坐标标准差5mm则认为该点可靠否则标记为unstable并跳过本次距离计算。该逻辑在tracker.py中实现使用scipy.spatial.distance.cdist批量计算历史轨迹相似度。# tracker.py 第63行 def update_stability_history(self, world_coords: np.ndarray): 更新每个目标的历史坐标序列并计算稳定性 for i, coord in enumerate(world_coords): if i len(self.history): self.history.append([coord]) else: self.history[i].append(coord) # 保留最近10帧 if len(self.history[i]) 10: self.history[i].pop(0) # 计算每条轨迹的标准差 stabilities [] for hist in self.history: if len(hist) 5: stabilities.append(False) else: arr np.array(hist) std_xyz np.std(arr, axis0) stabilities.append(np.all(std_xyz 0.005)) # 5mm阈值 return stabilities该函数返回布尔列表main.py中据此过滤掉抖动剧烈的目标点确保最终距离值具备工程可用性。4. 实战部署从零配置到输出三维距离的完整命令链4.1 环境搭建与依赖验证Ubuntu 20.04 / Windows 10项目已在Ubuntu 20.04WSL2和Windows 10Anaconda双平台验证。严禁使用pip install pyrealsense2——官方PyPI包不支持Python 3.9必须从源码编译或使用预编译wheel。Ubuntu 20.04步骤# 1. 安装RealSense SDK 2.50.0关键高版本SDK与D435i固件兼容性更佳 sudo apt-key adv --keyserver keys.gnupg.net --recv-key F6E65AC0F4886107 sudo add-apt-repository deb https://librealsense.intel.com/Debian/apt-repo focal main sudo apt-get update sudo apt-get install librealsense2-dkms librealsense2-dev librealsense2-utils # 2. 创建虚拟环境并安装Python依赖 python3 -m venv rs_env source rs_env/bin/activate pip install --upgrade pip pip install torch1.12.1cpu torchvision0.13.1cpu -f https://download.pytorch.org/whl/torch_stable.html pip install opencv-python4.8.1.78 pyrealsense22.50.0.5441 numpy1.23.5 # 3. 验证D435i识别 python -c import pyrealsense2 as rs; print(rs.__version__) # 应输出2.50.0.5441Windows 10步骤# 使用管理员权限PowerShell执行 # 1. 下载预编译wheel链接见项目README.md # 文件名pyrealsense2-2.50.0.5441-cp39-cp39-win_amd64.whl pip install pyrealsense2-2.50.0.5441-cp39-cp39-win_amd64.whl # 2. 安装其余依赖注意torch CPU版本 pip install torch1.12.1cpu torchvision0.13.1cpu -f https://download.pytorch.org/whl/torch_stable.html pip install opencv-python4.8.1.78 numpy1.23.5提示Windows下若出现ImportError: DLL load failed请确认已安装Visual C 2015-2019 Redistributablex64。4.2 模型权重与配置文件准备项目附带weights/yolov5s.ptYOLOv5s官方权重若需检测自定义类别如apple按以下流程微调准备标注数据集Pascal VOC或YOLO格式修改data/custom.yaml中nc: 1和names: [apple]执行迁移学习python train.py --img 320 --batch 16 --epochs 50 --data data/custom.yaml \ --weights weights/yolov5s.pt --name custom_apple训练完成后新权重位于runs/train/custom_apple/weights/best.pt。4.3 启动测距并验证输出# 基础运行检测person输出最近距离 python main.py --target-class person --min-conf 0.6 # 检测多个类别输出所有组合距离 python main.py --target-class cup,bottle --distance-mode all # 指定输出最长距离如测量桌面宽度 python main.py --target-class cup --distance-mode longest --max-dist 2.0首次运行时程序自动执行初始化D435i流RGBDepth640×48030fps加载YOLOv5模型并送入CPU推理显示实时画面绿色框标出检测目标左上角显示[cup_0] ↔ [cup_1]: 237.4 mm按q退出结果保存至logs/distances_20240515_142301.csv。验证要点观察终端是否打印[INFO] Depth stream aligned successfully检查画面中YOLOv5框是否与物体轮廓贴合若偏移需检查--img-size是否与训练尺寸一致用卷尺测量同一场景对比CSV中记录值与实测值偏差是否在±8mm内。5. 高阶技巧提升毫米级精度的四个硬核调参点5.1 D435i固件升级与深度图噪声抑制D435i出厂固件如5.12.12.50存在深度边缘锯齿问题。实测升级至5.14.25.0后1m内深度噪声标准差从±12mm降至±5mm。升级命令# Linux下使用rs-enumerate-devices确认设备ID rs-enumerate-devices -s # 下载固件包intelrealsense.github.io/firmware/ # 解压后执行假设固件文件为d435i_fw_5_14_25_0.bin sudo ./dfu-util -d 0x8086:0x0b0b -D d435i_fw_5_14_25_0.bin -a 0 -R升级后在代码中启用深度图后处理# 在main.py初始化部分添加 depth_to_disparity rs.disparity_transform(True) disparity_to_depth rs.disparity_transform(False) spatial rs.spatial_filter() temporal rs.temporal_filter() hole_filling rs.hole_filling_filter() # 将filters应用到depth_frame filtered depth_to_disparity.process(aligned_depth_frame) filtered spatial.process(filtered) filtered temporal.process(filtered) filtered disparity_to_depth.process(filtered) filtered hole_filling.process(filtered)这组滤波器组合可消除深度图中的孔洞与椒盐噪声尤其在物体边缘处效果显著。5.2 YOLOv5检测框中心点亚像素修正YOLOv5输出的bbox中心点是整数像素但真实目标中心常落在像素之间。项目采用梯度加权质心法提升定位精度# utils/centroid_refine.py def refine_centroid(rgb_crop: np.ndarray, depth_crop: np.ndarray) - Tuple[float, float]: 对RGB裁剪区域进行梯度加权质心计算返回亚像素级中心点 :param rgb_crop: 目标bbox对应的RGB图像块uint8 :param depth_crop: 对应深度图块float32单位米 :return: (x_subpix, y_subpix) 相对于crop左上角的亚像素坐标 # 计算RGB图像梯度幅值 grad_x cv2.Sobel(rgb_crop, cv2.CV_32F, 1, 0, ksize3) grad_y cv2.Sobel(rgb_crop, cv2.CV_32F, 0, 1, ksize3) grad_mag np.sqrt(grad_x**2 grad_y**2) # 深度图作权重深度越稳定权重越高 depth_weight 1.0 / (np.abs(depth_crop - np.median(depth_crop)) 0.01) # 加权质心 weight_map grad_mag * depth_weight y_indices, x_indices np.indices(weight_map.shape) x_cent np.sum(x_indices * weight_map) / np.sum(weight_map) y_cent np.sum(y_indices * weight_map) / np.sum(weight_map) return x_cent, y_cent该函数在inference.py中被调用替换原始整数中心点使三维坐标计算误差降低3.2mm实测数据。5.3 多帧深度融合策略单帧深度图受运动模糊影响较大。项目实现时间域深度融合对连续3帧的深度图做中值融合再取中心点深度值# 在main.py循环中维护深度帧队列 self.depth_buffer.append(aligned_depth_frame) if len(self.depth_buffer) 3: self.depth_buffer.pop(0) # 融合函数 def median_fuse_depth(frames: List[rs.frame]) - np.ndarray: depth_arrays [np.asanyarray(f.get_data(), dtypenp.uint16) for f in frames] stacked np.stack(depth_arrays, axis0) return np.median(stacked, axis0).astype(np.uint16)融合后深度图传入pixel_to_world()相比单帧1.5m距离测量标准差下降41%。5.4 世界坐标系原点偏移校准D435i深度传感器光学中心与RGB传感器不重合导致世界坐标系原点存在毫米级偏移。项目提供标定模板打印A4纸上的十字靶标固定于已知距离如1000mm处运行calibrate_origin.pypython calibrate_origin.py --distance 1000 --output origin_offset.npz该脚本采集10帧数据计算深度值均值与理论值偏差生成origin_offset.npz包含dx, dy, dz单位米。后续main.py自动加载并修正# 加载偏移量 if os.path.exists(origin_offset.npz): offset np.load(origin_offset.npz) world_coord[0] - offset[dx] world_coord[1] - offset[dy] world_coord[2] - offset[dz]此项校准可将系统性偏移从±15mm压缩至±2mm是达到“高分项目”精度的关键收尾动作。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门