news 2026/6/2 13:54:57

用Python和YOLOv5做个‘尺子’:手把手教你实现单目测距(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python和YOLOv5做个‘尺子’:手把手教你实现单目测距(附完整代码)

用Python和YOLOv5打造智能测距仪:从原理到落地的完整实践指南

在智能家居和工业自动化领域,物体距离测量一直是个有趣且实用的技术挑战。传统测距工具如卷尺或激光测距仪虽然精确,但缺乏智能化元素。本文将带您用普通摄像头和YOLOv5模型,构建一个能自动识别常见物体并计算距离的Python工具。这个项目完美融合了计算机视觉的趣味性与实用性,特别适合想深入理解单目视觉原理的技术爱好者。

1. 环境搭建与工具准备

工欲善其事,必先利其器。我们需要配置一个稳定的Python环境来运行YOLOv5和OpenCV。推荐使用Python 3.8+版本,这个版本在兼容性和性能上都有不错的表现。

首先创建并激活虚拟环境:

python -m venv distance_measure source distance_measure/bin/activate # Linux/Mac distance_measure\Scripts\activate # Windows

安装核心依赖库:

pip install torch torchvision opencv-python matplotlib numpy

注意:如果使用GPU加速,需要安装对应版本的PyTorch CUDA版本

YOLOv5的获取很简单,直接从官方仓库克隆即可:

git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt

常见问题排查:

  • 报错:ImportError: libGL.so.1: cannot open shared object file
    • 解决方案:sudo apt install libgl1-mesa-glx(Ubuntu)
  • 报错:DLL load failed while importing cv2
    • 解决方案:重新安装OpenCV:pip install --force-reinstall opencv-python-headless

2. 相机标定:获取关键参数

单目测距的核心公式是:

距离 = (物体实际宽度 × 焦距) / 图像中的像素宽度

要计算距离,我们需要先确定相机的焦距。这里介绍一种实用的标定方法:

  1. 准备一个已知尺寸的物体(如15cm宽的杯子)
  2. 在已知距离(如20cm)处拍摄该物体
  3. 用YOLOv5检测物体的像素宽度
  4. 代入公式计算焦距

焦距计算代码实现:

def calculate_focal_length(known_width, known_distance, pixel_width): return (pixel_width * known_distance) / known_width # 示例:杯子实际宽度15cm,拍摄距离20cm,检测到像素宽度为300px focal_length = calculate_focal_length(15, 20, 300) print(f"计算得到的焦距:{focal_length:.2f}像素")

标定质量检查表:

  • [ ] 物体与相机保持水平
  • [ ] 拍摄环境光线充足
  • [ ] 物体占据图像合理比例(建议30%-70%)
  • [ ] 多次测量取平均值

3. YOLOv5目标检测集成

YOLOv5提供了简洁的API接口,我们可以轻松集成到测距系统中。以下是一个检测并返回边界框的示例:

import torch # 加载预训练模型 model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True) def detect_objects(image_path): # 执行检测 results = model(image_path) # 提取杯子类别的检测结果(杯子在COCO数据集中类别为41) cups = results.pred[0][results.pred[0][:, 5] == 41] if len(cups) > 0: # 返回第一个检测到的杯子的边界框[x1,y1,x2,y2] return cups[0][:4].cpu().numpy() else: return None

常见检测问题优化:

问题现象可能原因解决方案
检测不到物体物体太小调整拍摄距离或使用更高分辨率
误检测率高背景复杂使用更精确的模型(yolov5m/l)
边界框抖动视频帧处理添加简单的跟踪算法

4. 距离计算与可视化

有了焦距和检测框,距离计算就水到渠成了。我们还需要考虑一些实际因素来提高精度:

def calculate_distance(known_width, focal_length, pixel_width, angle_correction=1.0): """ 计算物体到相机的距离 :param known_width: 物体实际宽度(cm) :param focal_length: 相机焦距(像素) :param pixel_width: 图像中物体宽度(像素) :param angle_correction: 角度校正因子(0.9-1.1) :return: 距离(cm) """ base_distance = (known_width * focal_length) / pixel_width return base_distance * angle_correction def visualize_result(image, bbox, distance): """在图像上绘制检测框和距离信息""" x1, y1, x2, y2 = bbox cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2) label = f"{distance:.1f}cm" cv2.putText(image, label, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) return image

精度提升技巧:

  • 多物体平均:检测同一物体的多个实例取平均值
  • 多帧平滑:视频流中使用移动平均减少抖动
  • 高度补偿:同时使用宽度和高度信息进行交叉验证

5. 完整系统集成与优化

将各个模块整合成一个完整的测距系统,以下是主程序的逻辑流程:

import cv2 from detection import detect_objects from calibration import calculate_focal_length class DistanceMeasurer: def __init__(self, known_width, calibration_distance): self.known_width = known_width self.calibration_distance = calibration_distance self.focal_length = None def calibrate(self, calibration_image): bbox = detect_objects(calibration_image) if bbox is not None: pixel_width = bbox[2] - bbox[0] self.focal_length = calculate_focal_length( self.known_width, self.calibration_distance, pixel_width) return True return False def measure(self, image_path): if self.focal_length is None: raise ValueError("请先校准相机") bbox = detect_objects(image_path) if bbox is not None: pixel_width = bbox[2] - bbox[0] distance = calculate_distance( self.known_width, self.focal_length, pixel_width) image = cv2.imread(image_path) return visualize_result(image, bbox, distance) return None

系统优化方向:

  • 性能优化:使用ONNX或TensorRT加速模型推理
  • 功能扩展:添加对多种物体的支持(书本、手机等)
  • 交互改进:开发简单的GUI界面
  • 部署方案:打包为独立可执行文件

6. 实际应用与误差分析

在实际测试中,我们发现几个影响精度的关键因素:

测试数据示例(杯子宽度15cm):

实际距离(cm)测量距离(cm)误差率(%)
3031.24.0
5052.85.6
100108.38.3

误差主要来源:

  1. 相机镜头畸变
  2. 物体与相机不平行
  3. 检测框位置偏差
  4. 标定时的测量误差

降低误差的实用技巧:

  • 使用棋盘格进行相机畸变校正
  • 保持被测物体与相机平行
  • 多次测量取平均值
  • 对不同距离区间使用不同的校正系数

在智能家居场景中,这个系统可以用来:

  • 测量快递包裹尺寸
  • 监控物品摆放位置
  • 辅助机器人导航避障
  • 智能储物空间管理
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 13:51:02

绝地求生罗技鼠标宏终极教程:3步快速实现零后坐力压枪

绝地求生罗技鼠标宏终极教程:3步快速实现零后坐力压枪 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 还在为《绝地求生》中难以控制…

作者头像 李华
网站建设 2026/6/2 13:47:48

告别报错!从UltraISO制作到Ubuntu安装完成的完整避坑实录

从UltraISO到Ubuntu:一次成功的系统安装全流程避坑指南引言:为什么你的Ubuntu安装总是失败?每次看到"Boot to PXE IPv4"这样的错误提示,我都忍不住想起自己第一次安装Ubuntu时的狼狈经历。明明按照教程一步步操作&#…

作者头像 李华
网站建设 2026/6/2 13:47:47

基于4G物联网与SHT20传感器的智能堆肥箱监测系统设计与实现

1. 项目概述与核心价值朋友在后院搞了个堆肥箱,想让我帮忙改造一下,核心需求就一个:他不想每次想知道堆肥发酵得怎么样时,都得跑过去掀开盖子、插个温度计,最好能像看天气预报一样,在手机或者电脑上随时看到…

作者头像 李华
网站建设 2026/6/2 13:43:56

AppStore技术支持网站

亲爱的用户 如果您在使用我们的产品时遇到任何问题,请随时与我们联系,我们将全力全意为您解决! 请发邮件与我们联系,我们将24小时为您服务! 邮箱地址:infoconow.cn 谢谢 Dear user If you encounter any pr…

作者头像 李华
网站建设 2026/6/2 13:41:00

DIY USB负载放电器:从原理到实践,精准测量电池容量

1. 项目概述:为什么你需要一个DIY的USB负载放电器?手头攒了一堆18650电池和移动电源,有的来自旧笔记本电池拆解,有的是朋友淘汰的“电子垃圾”。你肯定想过,这些电池到底还剩多少容量?那个宣称10000mAh的充…

作者头像 李华
网站建设 2026/6/2 13:34:43

Soundflower深度解析:Mac音频路由的终极解决方案

Soundflower深度解析:Mac音频路由的终极解决方案 【免费下载链接】Soundflower MacOS system extension that allows applications to pass audio to other applications. 项目地址: https://gitcode.com/gh_mirrors/sou/Soundflower 你是否曾为Mac上无法自由…

作者头像 李华