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

发布时间:2026/10/5 17:51:51
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.pyutils/下是工具函数general.py、metrics.py、loss.py、plots.py、datasets.py等train.py和detect.py是训练和推理入口。这部分和官方仓库基本一致说明作者没有魔改主干降低了理解成本。测距相关的核心文件有三个这是整份资源的灵魂文件作用依赖distance.py单目测距核心解算输入像素坐标输出物理距离相机内参、目标真实尺寸detect_A4.py用 A4 纸做标定和测距验证A4.mp4、best.ptrealsensedetect.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 python3.8 -y conda activate yolodist # 先装 PyTorch版本按你的 CUDA 来没有 GPU 就用 CPU 版 # CUDA 11.3 示例 pip install torch1.12.1cu113 torchvision0.13.1cu113 -f https://download.pytorch.org/whl/torch_stable.html # 再装其余依赖 pip install -r requirements.txt这里有个参数要说明Python 版本建议 3.8 或 3.93.10 以上部分旧版 torch 轮子可能找不到。CUDA 版本决定了你装哪个 torch 轮子cu113对应 CUDA 11.3cpu就是纯 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里如果锁定了torch1.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, labelpredicted) plt.axhline(ygt_distance, colorr, linestyle--, labelground truth) plt.xlabel(frame) plt.ylabel(distance (m)) plt.legend() plt.savefig(distance_curve.png)从那以后我每次拿到测距类项目都强制先跑一遍误差表再谈其他——没有量化误差的测距系统等于没有测距。这份资源的distance.py和detect_A4.py已经把框架搭好了你只需要把标定做扎实、把误差表填上毕设的实验部分就稳了。希望帮到你。本文还有配套的精品资源点击获取