news 2026/10/5 17:50:58

yolov5单目测距系统毕设拆解:从A4标定到误差量化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
yolov5单目测距系统毕设拆解:从A4标定到误差量化

简介:这份资源是经导师指导并获98分认可的毕业设计项目,围绕YOLOv5实现单目测距系统,面向计算机相关专业正在做毕设、课程设计或期末大作业的学生,也适合需要项目实战练习的学习者。项目已通过严格调试,可直接作为毕设使用。压缩包共78个文件,约215.32MB,以28个Python源码、26个YAML配置、6个Shell脚本为主,另含XML工程配置、JPG示例图、MP4演示视频、Dockerfile、预训练权重pt文件及说明文档,覆盖模型训练、推理检测与测距计算等环节。目录中可见detect.py、train.py、distance.py、realsensedetect.py等核心脚本,以及models、utils、data等模块,便于理解YOLOv5检测与单目测距的完整链路。目前已有180人学习下载,适合希望快速搭建可运行项目、对照源码梳理检测与测距实现思路的读者参考。

1. 从一份 98 分毕设拆起:yolov5 单目测距系统到底交付了什么

如果你正在做计算机方向的毕业设计,或者需要一个能写进简历的视觉项目,大概率刷到过「基于 yolov5 的单目测距系统」这类资源。我拿到这份压缩包的第一反应不是看代码,而是先确认它是不是一个能跑通的闭环:检测、测距、可视化、数据、权重,缺一个都只能算半成品。拆完之后结论是——它把 yolov5 检测和单目测距串成了一条完整链路,detect_A4.py、realsensedetect.py、distance.py三个文件分别对应 A4 纸标定、真实场景检测、距离解算,配合best.pt权重和A4.mp4测试视频,基本能做到解压即跑。

这份资源适合三类人:一是毕设选题卡在「目标检测 + 测距」方向、需要现成框架的学生;二是想拿一个完整项目练手、理解单目测距工程落地的学习者;三是课程设计或期末大作业需要交付可演示系统的同学。它不适合想从零手推公式的人,也不适合指望直接拿去发论文的场景——它的价值在于工程闭环,不是算法创新。下面我按「资源结构 → 环境搭建 → 测距原理与标定 → 训练与推理 → 避坑 → 进阶验证」的顺序,把这份包拆开讲透。

2. 资源结构与运行环境:先搞清楚每个文件干什么

2.1 目录拆解与核心文件定位

拿到压缩包别急着pip install,先花五分钟把目录结构过一遍,能省掉后面大量「文件找不到」的玄学问题。这份资源的目录大致分四块:yolov5 主干代码、测距相关脚本、配置与权重、测试素材。

主干部分就是标准的 yolov5 仓库结构,models/下是网络定义(yolov5s.yaml到yolov5x.yaml五个规格,还有common.py、experimental.py、yolo.py),utils/下是工具函数(general.py、metrics.py、loss.py、plots.py、datasets.py等),train.py和detect.py是训练和推理入口。这部分和官方仓库基本一致,说明作者没有魔改主干,降低了理解成本。

测距相关的核心文件有三个,这是整份资源的灵魂:

文件作用依赖
distance.py单目测距核心解算,输入像素坐标输出物理距离相机内参、目标真实尺寸
detect_A4.py用 A4 纸做标定和测距验证A4.mp4、best.pt
realsensedetect.py真实场景下的检测 + 测距RealSense 相机或普通摄像头

配置和权重方面,data/下有coco128.yaml、coco.yaml、voc.yaml、argoverse_hd.yaml等数据集配置,weights/best.pt是训练好的权重,yolov5s.pt是官方预训练权重,download_weights.sh负责拉取权重。hyp.finetune.yaml和hyp.scratch.yaml是两套超参配置,前者用于微调,后者用于从头训练。

测试素材给了A4.mp4,这个设计很聪明——A4 纸尺寸已知(210mm × 297mm),用它做测距验证,真值明确,方便你判断测距模块到底准不准。

提示:.idea/目录是 PyCharm 的工程配置,yolov5-main.iml、vcs.xml、misc.xml这些是 IDE 文件,不影响运行,但说明作者是在 PyCharm 里开发的,用其他编辑器的话可以忽略。

2.2 环境搭建与依赖安装

环境这块,yolov5 对 PyTorch 版本比较敏感,我一般建议先看requirements.txt再动手。这份资源的依赖清单是标准 yolov5 那一套,核心是torch、torchvision、opencv-python、numpy、pyyaml、tqdm、matplotlib、pillow。

# 建议用 conda 建独立环境,避免和系统 Python 打架 conda create -n yolodist python=3.8 -y conda activate yolodist # 先装 PyTorch,版本按你的 CUDA 来,没有 GPU 就用 CPU 版 # CUDA 11.3 示例 pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html # 再装其余依赖 pip install -r requirements.txt

这里有个参数要说明:Python 版本建议 3.8 或 3.9,3.10 以上部分旧版 torch 轮子可能找不到。CUDA 版本决定了你装哪个 torch 轮子,cu113对应 CUDA 11.3,cpu就是纯 CPU。如果你不确定自己的 CUDA 版本,跑nvidia-smi看右上角的CUDA Version。

装完之后验证一下:

python -c "import torch; print(torch.__version__, torch.cuda.is_available())"

输出里True表示 GPU 可用,False就是 CPU 模式。CPU 也能跑推理,只是慢,训练就别想了。

权重文件如果weights/best.pt已经在了,直接跳过下载。如果缺失,download_weights.sh里是拉取脚本,但注意它默认拉的是官方预训练权重,不是这份项目的best.pt。best.pt是作者训练好的,丢了就得自己重训,这个后面训练章节会讲。

注意:requirements.txt里如果锁定了torch>=1.7.0这种宽范围,pip 可能给你装最新版,反而和代码不兼容。稳妥做法是手动指定 torch 版本,别完全交给 pip 解析。

3. 单目测距原理与 A4 标定:像素怎么变成米

3.1 相似三角形测距的数学基础

单目测距的核心就一个公式,但坑全在参数上。原理是相似三角形:已知目标真实宽度W,在图像中占w像素,相机焦距f(像素单位),那么目标到相机的距离D满足:

D = (W × f) / w

这个公式成立的前提是目标平面和相机光轴垂直,且目标尺寸已知。A4 纸之所以适合做标定,就是因为它的宽高是标准值(210mm × 297mm),真值确定,测出来的距离准不准一眼就能判断。

焦距f怎么来?两个途径:一是查相机规格书,二是自己标定。规格书给的焦距通常是毫米单位,要换算成像素:f_pixel = f_mm × 图像宽度 / 传感器宽度。自己标定更靠谱,用已知距离和已知尺寸的目标反推。

distance.py里封装的就是这套解算逻辑,输入是检测框的像素宽高和预设的真实尺寸,输出是距离。我拆了一下,核心函数大概长这样:

# distance.py 核心逻辑示意 def calculate_distance(pixel_width, real_width, focal_length): """ pixel_width: 检测框像素宽度 real_width: 目标真实宽度(米) focal_length: 相机焦距(像素) 返回:目标到相机的距离(米) """ if pixel_width <= 0: return -1 # 防止除零 distance = (real_width * focal_length) / pixel_width return distance

逻辑说明:pixel_width来自 yolov5 检测框的宽度,real_width是你预设的目标物理宽度,focal_length是标定得到的焦距。三个参数里,real_width和focal_length的误差会直接线性放大到距离结果上,所以标定环节不能糊弄。

参数说明:real_width单位要和focal_length保持一致,都用米或都用毫米,混用就是经典翻车点。focal_length的标定精度决定了整体精度,建议用多个距离点拟合,而不是单点反推。

3.2 用 A4.mp4 做焦距标定与精度验证

detect_A4.py配合A4.mp4就是干这个的。操作步骤:

第一步,先跑一遍检测,确认best.pt能正常识别 A4 纸(或者识别的是 A4 纸上的目标,取决于训练类别)。

python detect_A4.py --weights weights/best.pt --source A4.mp4 --view-img

参数说明:--weights指定权重路径,--source指定输入视频,--view-img实时显示检测结果。如果报错找不到best.pt,检查weights/目录是否存在,或者路径写的是相对路径还是绝对路径。

第二步,从检测结果里读出 A4 纸在画面中的像素宽度,结合已知真实宽度 0.21 米,反推焦距:

# 标定焦距:已知距离和像素宽度反推 known_distance = 1.0 # 标定时 A4 纸到相机的实际距离,单位米 pixel_width = 320 # 该距离下检测框的像素宽度 real_width = 0.21 # A4 纸真实宽度,单位米 focal_length = (pixel_width * known_distance) / real_width print(f"标定焦距: {focal_length:.2f} 像素")

逻辑说明:这是测距公式的逆运算。你先量出相机到 A4 纸的实际距离(用卷尺,别估),再从画面里读出像素宽度,代入反推焦距。参数说明:known_distance一定要实测,pixel_width建议取多帧平均,单帧有抖动。

第三步,用标定好的焦距去测其他距离,验证误差:

# 验证:用标定焦距测新距离 test_pixel_width = 160 # 新位置下 A4 纸像素宽度 predicted_distance = (real_width * focal_length) / test_pixel_width print(f"预测距离: {predicted_distance:.2f} 米")

如果预测距离和实测距离误差在 5% 以内,标定就算合格。超过 10%,要么焦距标错了,要么目标平面和光轴不垂直,要么检测框抖动太大。

提示:A4 纸标定的最大价值是给你一个「真值可控」的验证环境。真实场景里目标尺寸未知、姿态多变,误差会大很多,所以别拿 A4 的精度去承诺真实场景的精度。

3.3 焦距、真实尺寸与检测框的三角关系

这三个参数是测距精度的铁三角,任何一个出问题,结果都会偏。焦距标定错了,所有距离系统性偏移;真实尺寸设错了,距离按比例缩放;检测框抖动,距离就跳变。

检测框抖动是工程里最烦的,因为模型输出本身就有波动。常见做法是对连续多帧的检测框做滑动平均,或者用卡尔曼滤波平滑。realsensedetect.py里如果用了 RealSense,还能拿到深度信息做交叉验证,但纯单目就只能靠滤波。

真实尺寸这块,如果你检测的是固定类别(比如锥桶、行人),可以预设一个平均尺寸。但行人高矮胖瘦差异大,测距误差自然大。这也是单目测距的边界——它适合尺寸相对固定的目标,不适合尺寸变化剧烈的类别。

4. 训练自己的数据集与推理调参

4.1 数据集配置与 hyp 超参选择

如果你想用自己的数据重训,data/下的 yaml 就是入口。以coco128.yaml为模板,改成自己的路径和类别:

# data/mydata.yaml train: ../mydata/images/train val: ../mydata/images/val nc: 3 names: ['person', 'cone', 'car']

参数说明:train和val是图片目录路径,nc是类别数,names是类别名列表,顺序要和标注文件里的 class id 对应。标注格式是 yolov5 标准的 txt,每行class x_center y_center width height,坐标归一化到 0-1。

超参选择上,hyp.finetune.yaml用于微调——你已经有best.pt或者官方预训练权重,只想在自己的小数据集上适配,学习率低、epoch 少。hyp.scratch.yaml用于从头训练,学习率高、数据增强强。毕设场景一般用微调就够了,除非你的类别和预训练差异极大。

# 微调训练 python train.py --data data/mydata.yaml --weights weights/best.pt --cfg models/yolov5s.yaml --hyp data/hyp.finetune.yaml --epochs 50 --batch-size 16 --img 640

参数说明:--weights指定初始权重,微调时用预训练权重收敛快;--cfg指定网络结构,yolov5s最轻量,yolov5x最重但精度高;--epochs训练轮数,小数据集 50 够用;--batch-size按显存调,8G 显存跑yolov5s用 16 差不多;--img输入尺寸,640 是默认值。

4.2 推理脚本参数与测距联动

训练完得到新的best.pt,推理入口是detect.py。但这份资源的重点在测距,所以要看detect_A4.py和realsensedetect.py怎么把检测结果喂给distance.py。

# 标准检测推理 python detect.py --weights weights/best.pt --source data/images --conf-thres 0.5 --iou-thres 0.45 --img-size 640

参数说明:--conf-thres置信度阈值,低于这个值的框被丢弃,调高减少误检但可能漏检;--iou-thresNMS 的 IoU 阈值,控制重叠框合并;--img-size推理尺寸,要和训练时一致,否则精度掉。

测距联动部分,核心是从检测结果里取出框的像素宽度,传给distance.py:

# 检测 + 测距联动示意 from distance import calculate_distance focal_length = 800.0 # 标定得到的焦距 real_width = 0.21 # 目标真实宽度 for *xyxy, conf, cls in det: pixel_width = xyxy[2] - xyxy[0] # 框的像素宽度 dist = calculate_distance(pixel_width, real_width, focal_length) print(f"类别 {cls} 距离 {dist:.2f} 米")

逻辑说明:xyxy是检测框的左上角和右下角坐标,xyxy[2] - xyxy[0]就是像素宽度。参数说明:focal_length和real_width必须和标定时一致,换相机就要重新标定。

注意:--img-size改了之后,检测框的像素坐标会跟着缩放,焦距也要按比例调整,否则测距全错。这是很多人换分辨率后测距突然不准的原因。

5. 避坑与常见问题排查

5.1 权重加载失败与路径问题

现象:运行detect_A4.py报FileNotFoundError: weights/best.pt或者RuntimeError: Error(s) in loading state_dict。

原因:一是best.pt文件缺失或路径写错,二是权重和网络结构不匹配(比如用yolov5s.pt的权重去加载yolov5x.yaml的结构)。

解决:先确认weights/目录下文件存在,用绝对路径排除相对路径歧义。结构不匹配的话,检查--cfg和权重是否对应,yolov5s的权重只能配yolov5s.yaml。如果只是缺权重,用download_weights.sh拉官方预训练权重先跑通流程,再换自己的。

5.2 测距数值跳变或明显偏大偏小

现象:距离输出在几米范围内乱跳,或者稳定偏大/偏小一个固定比例。

原因:跳变通常是检测框抖动,偏大偏小是焦距或真实尺寸标定错误。

解决:跳变问题对多帧做滑动平均,窗口取 5-10 帧。偏大偏小先检查real_width单位,0.21 米写成 21 厘米就是 100 倍误差。再检查焦距标定时的known_distance是不是实测值,估的值必然偏。

5.3 CUDA 显存不足与 CPU 回退

现象:训练或推理时报CUDA out of memory。

原因:--batch-size或--img-size太大,显存扛不住。

解决:先降--batch-size到 8 或 4,再降--img-size到 416。还不行就加--device cpu强制 CPU,慢但能跑。推理阶段显存占用比训练小很多,一般不会 OOM。

5.4 检测框坐标与测距公式的坐标系不一致

现象:测距结果和实际差一个数量级,或者随目标位置变化规律不对。

原因:检测框坐标是相对原图的,但如果你做了 resize 或 letterbox,坐标被缩放了,焦距没跟着调。

解决:确认推理时的--img-size和标定焦距时的分辨率一致。如果必须改分辨率,焦距按新焦距 = 原焦距 × 新宽度 / 原宽度等比缩放。letterbox 的填充偏移也要考虑进去,否则框位置会偏。

5.5 A4 标定准但真实场景不准

现象:A4 纸测距误差 3%,换成真实目标误差 30%。

原因:A4 纸是平面正对相机,真实目标有姿态角、尺寸不一致、部分遮挡。

解决:这是单目测距的固有边界,不是代码 bug。能做的优化是选尺寸稳定的目标类别,加姿态估计补偿,或者引入深度相机做融合。别指望纯单目在所有场景都准。

6. 进阶验证:把测距误差量化成一张表

跑通只是第一步,毕设答辩时老师大概率会问「你这个测距精度多少」。与其含糊说「挺准的」,不如做一张误差表,用数据说话。我的习惯是固定几个距离点,每个点测 30 帧,算平均误差和标准差。

import numpy as np # 误差统计:每个距离点采集多帧 def evaluate_distance(pred_list, gt_distance): """ pred_list: 多帧预测距离列表 gt_distance: 实测真值 """ pred_arr = np.array(pred_list) mean_pred = pred_arr.mean() std_pred = pred_arr.std() abs_error = abs(mean_pred - gt_distance) rel_error = abs_error / gt_distance * 100 print(f"真值 {gt_distance}m | 预测均值 {mean_pred:.3f}m | 标准差 {std_pred:.3f}m | 绝对误差 {abs_error:.3f}m | 相对误差 {rel_error:.1f}%") return rel_error # 示例:1 米处采集 30 帧 preds_1m = [0.95, 1.02, 0.98, 1.05, 0.97] * 6 evaluate_distance(preds_1m, 1.0)

逻辑说明:pred_list是同一距离下多帧的预测值,gt_distance是卷尺实测真值。参数说明:帧数建议 30 以上,少了统计意义不足;真值一定要实测,别用另一个测距工具的值当真值,那是循环论证。

把 0.5m、1m、2m、3m 几个点的结果整理成表:

真值(m)预测均值(m)标准差(m)相对误差
0.50.520.034.0%
1.00.970.043.0%
2.02.110.085.5%
3.03.240.128.0%

这张表能直接写进毕设论文的实验章节,也能在答辩时堵住「精度多少」的追问。规律很明显:距离越远,相对误差越大,因为像素宽度变小,同样的像素误差对应的物理误差被放大。这是单目测距的物理极限,不是调参能解决的。

还有一个验证技巧:把A4.mp4里每一帧的测距结果和真值画成曲线,看跟踪是否平滑。如果曲线锯齿严重,说明检测框抖动大,加滤波;如果曲线整体偏移,说明标定参数错。这个可视化用 matplotlib 几行就能画:

import matplotlib.pyplot as plt plt.plot(range(len(preds)), preds, label='predicted') plt.axhline(y=gt_distance, color='r', linestyle='--', label='ground truth') plt.xlabel('frame') plt.ylabel('distance (m)') plt.legend() plt.savefig('distance_curve.png')

从那以后我每次拿到测距类项目,都强制先跑一遍误差表再谈其他——没有量化误差的测距系统,等于没有测距。这份资源的distance.py和detect_A4.py已经把框架搭好了,你只需要把标定做扎实、把误差表填上,毕设的实验部分就稳了。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 17:47:45

拆解六款开源RAG项目:自研检索链路的核心设计与实践避坑指南

先说结论&#xff1a;RAG项目“看着能跑&#xff0c;一上量就废”的真相&#xff0c;往往不在大模型&#xff0c;而在检索链路。做自研RAG的人&#xff0c;早晚会对“开源项目”产生一种复杂情绪。一方面知道有那么多现成产品可以参考&#xff0c;另一方面又觉得LangChain太散、…

作者头像 李华
网站建设 2026/10/5 17:36:47

增强版RAG知识库实战:Agent驱动检索与HyDE重排序优化

1. 从"能查"到"会想"&#xff1a;增强版知识库到底增强了什么很多人做 RAG 知识库&#xff0c;第一步就跑偏了。他们把文档切碎、灌进向量库、接一个大模型&#xff0c;然后兴冲冲地问一句"我们公司的报销标准是多少"&#xff0c;结果模型答得驴…

作者头像 李华
网站建设 2026/10/5 17:34:03

技术逆向英语:工程师从英文文档倒推输入的高效学习法

做技术这行十年下来&#xff0c;我见过太多人英文资料查得飞快、阅读量惊人&#xff0c;但一到开口讲技术方案、写英文邮件就卡壳。我自己也经历过这个阶段&#xff0c;从大学四级边缘水平的英语渣&#xff0c;到后来能用英文主持跨时区会议、技术方案被境外客户直接点名表扬&a…

作者头像 李华
网站建设 2026/10/5 17:34:03

Python回文串检测实战:从双指针到Manacher算法与踩坑总结

面试里几乎必考、实际工程项目里也经常绕不开的Python回文串检测&#xff0c;我在第三次被这道题“坑”了之后&#xff0c;终于决定把完整的思路、写法和踩坑记录整理出来。起因很简单&#xff1a;有一次笔试题目要求判断一个句子中每个单词是否构成回文串&#xff0c;我一开始…

作者头像 李华
网站建设 2026/10/5 17:34:03

医疗IoT设备安全:MQTT协议漏洞与远程操作模型防护指南

医疗IoT设备控制基础&#xff1a;MQTT协议漏洞与远程操作模型医疗行业这几年联网设备的增长速度&#xff0c;说实话比我预想中快太多了。病房里心电监护、输液泵、血糖仪、智能床垫、中央监护大屏&#xff0c;背后基本都挂在一个统一的消息通道上。你去看这些设备底层的通信协议…

作者头像 李华
网站建设 2026/10/5 17:25:19

OpenShell实战:恢复高效经典的Windows开始菜单

手里这台Windows 10笔记本&#xff0c;我已经用了整整五年&#xff0c;系统更新过无数次&#xff0c;唯一没换过的就是开始菜单。很多人好奇&#xff1a;为什么不直接用系统自带的&#xff1f;因为从Windows 8开始&#xff0c;微软就把开始菜单从一个纯粹的“启动工具”变成了“…

作者头像 李华