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

YOLOv5与Tello TT无人机:目标识别、追踪与测距实战解析

简介一份基于YOLOv5与大疆教育无人机Tello TT的目标识别追踪完整工程包专为深度学习、计算机视觉方向需要实战项目的学习者准备尤其适合毕业设计、课程设计与期末大作业场景。项目通过旗和圈两类目标完成数据集标注与训练模型已经调优可直接用于无人机视觉识别、定位与追踪测距实验也可基于代码自行扩展新类别。压缩包共1672个文件约269.18MB包含758张图像样本、694个标注文本、50个Python脚本、94个YAML配置以及训练好的模型pt和详细操作说明文档内容预览中还有多个TensorFlow事件日志可用于分析训练收敛过程辅助排错。目前已有283人学习下载对需要快速落地YOLOv5无人机项目的同学而言是省时省力的直接可用资料也适合在此基础上做二次开发与学习借鉴。1. 用 YOLOv5 给 Tello TT 做目标识别这份源码包里到底有什么做毕设或者课程设计的人看到“YOLOv5 大疆教育无人机 Tello TT”这套组合第一反应往往是代码能不能直接跑、数据集够不够用、追踪测距到底怎么算出来的。这份资源不是给你一个半成品然后让你自己补而是把目标识别检测、追踪、测距三条线都串好了配套带数据集和训练好的权重目标对象是旗和圈两类。适合两类人正在做视觉识别方向毕设的学生以及想把 YOLOv5 跑到真实硬件上、看看端到端流程怎么走的开发者。整包包含源码、模型权重、数据集和操作说明我拆完后给你说清楚每一块怎么用、参数怎么改、坑在哪。2. 环境搭建与目录结构先让代码在今天跑起来2.1 源码包目录拆解压缩包解开后第一件事不是急着跑训练而是先盘清楚目录结构。我拆完这份包典型的 YOLOv5 工程布局外加无人机控制相关的代码和文档核心路径大致如下project_root/ ├── yolov5/ # 主检测工程 │ ├── train.py # 训练入口 │ ├── detect.py # 推理入口 │ ├── data/ # 数据配置 yaml 与标签 │ ├── models/ # 网络结构定义 │ ├── runs/ # 训练输出权重、日志 │ └── requirements.txt # Python 依赖 ├── tello/ # Tello TT 控制与追踪逻辑 ├── datasets/ # 旗、圈标注数据集 ├── weights/ # 训练好的模型文件 └── 操作说明文档.pdfevents.out.tfevents.*这一串时间序列文件是训练时 TensorBoard 留下的日志分布在 runs 目录下说明这份模型的训练曲线是完整的不是凭空丢给你一个权重文件。先检查requirements.txt里的 PyTorch 和 torchvision 版本再对照当前 Python 环境。常见的坑是 PyTorch 装的是 CPU 版训练直接慢到怀疑人生或者 torchvision 和 PyTorch 版本不匹配detect 阶段报AttributeError。2.2 用 conda 建独立环境我一般习惯用 conda 建一个干净环境不用系统级 Python避免依赖互相污染。步骤是创建 Python 3.8 环境、激活、进到 yolov5 目录装 requirements、额外装一个tensorboard用来后续看训练日志。conda create -n tello_yolo python3.8 -y conda activate tello_yolo cd yolov5 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install tensorboardrequirements.txt会装 PyTorch、OpenCV、numpy、matplotlib 等。国内网络环境建议用清华源不然装 PyTorch 那个体积容易卡到超时。装完后跑一句python -c import torch; print(torch.cuda.is_available())如果输出False说明当前是 CPU 环境训练只能硬啃。有 N 卡的话建议重装 CUDA 版 PyTorch版本选择对照 PyTorch 官网的 CUDA 版本表来。2.3 本地推理跑通 demo环境就绪后先用训练好的模型跑一次推理确认权重文件能正常加载。官方权重和自训权重在detect.py里通过--weights指定--source可以是图片、视频或者摄像头。Tello TT 的场景下通常先用一段录好的视频验证检测框稳定再接实时流。python detect.py \ --weights ../weights/best.pt \ --source ../datasets/test.mp4 \ --conf 0.4 \ --iou 0.45 \ --save-txt \ --project ../runs/detect--conf 0.4表示置信度低于 0.4 的框直接丢弃--iou 0.45是 NMS 的 IoU 阈值。如果你发现检测框跳得厉害同一目标时有时无把 conf 降到 0.25 试试如果框一堆叠在一起分不开把 iou 降到 0.3。跑完后在runs/detect下能看到带框的视频--save-txt会额外导出每个目标的类别、置信度、归一化坐标后面做追踪测距就要靠这些 txt 数据。3. 旗与圈数据集的训练调优从 data.yaml 到 TensorBoard 日志怎么看3.1 数据集结构与本包标注格式这份数据集只有两类旗flag和圈circle。YOLOv5 训练要求图片和标注文件一一对应标注是 YOLO 格式的 txt每行代表一个目标class x_center y_center width height四个坐标都是相对于图片宽高的归一化值。目录结构如下datasets/ ├── images/ │ ├── train/ # 约 80% 图片 │ └── val/ # 约 20% 图片 ├── labels/ │ ├── train/ # 同名 txt 标注 │ └── val/ └── data.yamldata.yaml是训练入口里面写类别数和类别名路径建议写成相对路径避免换机器后路径失效train: ../datasets/images/train val: ../datasets/images/val nc: 2 names: [flag, circle]如果你打算拿这份数据训练自己的模型先检查有没有图片有标注但对应 txt 为空的情况以及有没有标注框越界坐标大于 1 或小于 0。这类脏数据不影响加载但会污染训练导致 loss 曲线很奇怪。3.2 训练参数怎么改训练命令本身不复杂拉通一次后重点就在超参数上。这份包里的模型已经调优过如果只是想复现效果可以直接用预训练权重继续--weights微调不用从头训练。从头训或从 YOLOv5s 官方权重迁移命令如下python train.py \ --data ../datasets/data.yaml \ --cfg ../models/yolov5s.yaml \ --weights yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --imgsz 640 \ --device 0 \ --patience 20--epochs 100是训练轮数--patience 20表示验证集指标连续 20 轮不提升就自动早停。这两个参数是时间和精度的平衡器机器是 20 系显卡起步100 轮大约 1 到 2 小时如果是 CPU 训练建议把 batch-size 降到 4、imgsz 降到 416 先跑通再慢慢加。--batch-size要根据显存调我最常遇到的问题就是显存不够爆CUDA out of memory备份做法是把 imgsz 降一档。--device 0指定第一块 GPU--device cpu则是纯 CPU 模式。3.3 训练中期的检视手段TensorBoard刚才提到包里有大量events.out.tfevents.*说明训练过程开了 TensorBoard 日志。训练时 YOLOv5 会自动把标量写入runs/train/exp*目录训练中途开另一个终端就能实时看tensorboard --logdir runs/train --port 6006浏览器访问http://localhost:6006重点看三条曲线train/box_loss、val/box_loss和metrics/mAP_0.5。如果 box_loss 下降但 mAP 不动大概率是标注有问题或者类别不均衡如果 loss 下降后快速反弹过拟合说明 epochs 太多或者数据集太小可以把 patience 调低。这个包里 tfevents 时间戳跨度从 2021 年 12 月到 2022 年 1 月多轮实验记录都在代表作者是分阶段调参的——先是数据准备然后试跑再调超参。你复现时如果发现 mAP 到不了文档里写的值先对比你用的imgsz和作者训练时是否一致。YOLOv5 在 640 和 320 输入下的 mAP 差得不是一点点。4. 追踪测距实现:像素坐标换算、丢包重发与轨迹跟随4.1 Tello TT 通信协议与实时帧获取Tello TT 走的是一套基于 UDP 的 SDK 协议控制端口 8889视频流通过 RTSP 拉取。官方 SDK 的指令格式是字符串命令 udp发送比如command进入 SDK 模式、takeoff起飞、streamon打开图传。源码包里控制代码的核心逻辑一般是维护一个 UDP socket 和一个视频解码线程import socket import threading import av TELLO_IP 192.168.10.1 TELLO_PORT 8889 LOCAL_PORT 9000 sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((, LOCAL_PORT)) sock.settimeout(0.5) tello_addr (TELLO_IP, TELLO_PORT) def send_cmd(cmd): sock.sendto(cmd.encode(utf-8), tello_addr) try: resp, _ sock.recvfrom(128) return resp.decode(utf-8) except socket.timeout: return timeout # RTSP 视频流解码 container av.open(rtsp://192.168.10.1:8554/video0) for frame in container.decode(video0): img frame.to_ndarray(formatbgr24) # 这里把 img 丢给 YOLOv5 推理send_cmd里加了 0.5 秒超时因为 Tello 的 Wi-Fi 是弱项指令经常丢包。常见做法是检测到timeout就重发重发次数超过 3 次后报错而不是一直死等。视频流用 PyAV 解比 OpenCV 的VideoCapture稳cv2.VideoCapture(rtsp://...)在 Tello 上经常起流失败PyAV 对 H.264 裸流的兼容性更好。4.2 测距固定高度下的像素尺度换算测距是这套系统里最有“玄学”色彩的部分。没有双目相机、没有激光测距怎么用单目摄像头算出距离答案是标定。Tello TT 悬停时高度固定摄像头朝下或朝前目标在图像中的像素宽度和真实宽度满足一个近似线性关系distance (real_width * focal_length) / pixel_widthfocal_length可以通过标定得到更简单的做法是“实测标定法”——无人机悬停在已知高度目标放在不同距离记录检测框像素宽度拟合一条曲线。给一段示例def estimate_distance(pixel_width, real_width_cm, focal_px): if pixel_width 0: return -1 return (real_width_cm * focal_px) / pixel_width # 标定示例: focal_px 由标定得到通常 Tm 系列镜头在 640x480 下约 700~900 distance_cm estimate_distance(bbox_width_px, real_width_cm30, focal_px800)注意这是平面测距前提是目标平面与相机成像面近似平行。实际飞行中如果目标斜着放测出来的距离偏大误差随角度增大。想要稳就得把无人机姿态角pitch/roll读出来做投影校正包里一般是做一个简化版只假设相机光轴与地面垂直忽略姿态角。4.3 追踪控制误差到舵量的闭环追踪的本质是让目标框的中心点始终逼近图像中心。检测脚本输出目标框后计算水平和垂直方向的像素偏差映射成 Tello 的rc遥控指令rc left_velocity forward_velocity up_velocity yaw_rate取值范围 -100 到 100。控制逻辑是典型 PID 比例项先做一个简单的 P 控制器验证# 伪代码控制周期建议 200ms太短 Tello 反应不过来 get bbox from yolov5 error_x (bbox.cx - img.cx) / img.cx error_y (bbox.cy - img.cy) / img.cy rc_left int(error_x * 50) # 水平平移速度 rc_yaw int(error_x * 30) # 转向速度优先级低于 rc_left rc_up int(-error_y * 20) # 高度微调 send_cmd(rc {} {} {} {}.format(rc_left, 0, rc_up, rc_yaw))这里我加了死区判断当abs(error_x) 0.05时认为目标已居中rc全部置 0否则飞机会因为像素抖动来回摆头。YOLOv5 检测框在多帧之间会轻微跳动不做死区处理画面会很难看而且 Tello 的电机频繁正反切换损耗很大。P 系数从 30 到 50 之间开始调太大了横幅震荡太小了跟不住。距离控制同理目标框像素宽度大于目标值说明太近给负前向速度小于则给正前向速度形成完整追踪闭环。5. 常见问题避坑Wi-Fi 丢包、版本错配与训练翻车记录5.1 现象Tello 起飞后指令延迟明显追踪框来回跳原因Tello TT 自带的是 2.4G Wi-Fi在实验室或教室这种 Wi-Fi 密集环境干扰极多UDP 控制包和视频流共用一个信道带宽被视频流吃掉大半控制指令排队。解决不要把控制循环和推理循环放在同一个线程里。推理是一个线程持续从队列取帧控制是另一个线程按固定周期从最近一帧检测结果读取目标位置发送rc指令。视频分辨率从 960p 降到 480p用set_video_resolution指令把图传改低实测延迟能从 300ms 降到 150ms 以内追踪稳定性明显提升。5.2 现象detect.py 加载权重时报RuntimeError: Model has been compiled with a newer version of PyTorch原因权重文件不是纯模型参数里面打包了训练时的 PyTorch 版本信息。包作者训练环境和我本地环境版本不一致低版本 PyTorch 读不了高版本权重。解决先看weights目录里有没有best.pt和last.pt优先加载last.pt如果两个都报错用torch.load(path, map_locationcpu)手动加载后检查model键再重新save一遍。最保险的做法是直接按requirements.txt里的版本重建环境不要用最新的 PyTorch 去兼容旧权重。5.3 现象训练时 loss 是nanTensorBoard 曲线断掉原因标注文件里出现了 0 宽度或 0 高度的框或者坐标越界被归一化后变成负数。YOLOv5 的数据加载器不校验合法性这类标注会直接让 loss 计算崩溃。解决写一个清洗脚本扫描 labels 目录删掉包含0或负数的行顺便过滤掉没有标注的图片import os label_dir datasets/labels/train for name in os.listdir(label_dir): path os.path.join(label_dir, name) lines open(path).readlines() valid [] for line in lines: parts line.strip().split() if len(parts) ! 5: continue _, x_c, y_c, w, h parts if float(w) 0 and float(h) 0: if 0 float(x_c) 1 and 0 float(y_c) 1: valid.append(line) with open(path, w) as f: f.writelines(valid)这段脚本是数据清洗的兜底操作任何拿别人数据集训练的场景都用得上。跑完后重新统计每张图标注数确保没有空洞。5.4 现象Tello 检测到目标但无法靠近速度始终为 0原因rc指令的四个通道参数值域是 -100 到 100但 0 不代表“保持”而是“该通道不发送指令”。当我把forward_velocity设成 0 时Tello 理解成不发送前进通道导致只有转向没有前进看起来像电机锁死。解决rc指令中所有通道必须显式赋值不能省略。需要停止时发送rc 0 0 0 0表示全通道制停而不是只把要用的通道写出来。循环里每次迭代都构建完整的四通道字符串杜绝参数拼接漏项。5.5 现象Wi-Fi 掉线后无人机进入紧急降落代码抛socket.timeout后卡死原因Tello 的 UDP 指令没有应答确认机制掉线时recvfrom会一直阻塞如果没设超时整个控制线程挂死。解决给sock.settimeout(0.5)加超时然后写一个断线重连逻辑连续 5 次超时后主动发送command重新进入 SDK 模式同时把追踪线程暂停等recvfrom恢复后再续。这套机制在这份源码的基础上补上后实际飞行中掉线也能自动恢复不用手动拔电池重启。6. 进阶用法用检测框做测距标定 把模型部署到树莓派前面讲的测距是基于固定焦距的简化版实际用的时候你会发现同一台无人机在不同分辨率下的focal_px不一样。进阶做法是重新标定把无人机悬停在已知高度放一个已知宽度的旗帜通过检测框像素宽度反推焦距然后记录不同距离下的数据做二次校验。我习惯的做法是这样一张标定表目标距离(m)旗帜真实宽度(cm)检测框像素宽度(px)推算焦距(focal_px)1.0302688931.5301788902.030134893三组数据算出来焦距几乎一致说明标定可靠。如果某个距离下偏差超过 5%检查是不是目标不完整、检测框截断了旗帜边缘。标定完成后把焦距写进配置文件就不要再动了。部署方向上如果你手头有树莓派或者类似的低功耗板子可以把训练好的best.pt转成 TensorRT 或者 ONNX 再上板。YOLOv5 官方提供了export.py转 ONNX 的命令是python export.py \ --weights ../weights/best.pt \ --include onnx \ --imgsz 640转完的best.onnx体积比 PyTorch 权重小一圈用 ONNX Runtime 推理速度在树莓派 4B 上能到 8-12 FPS做地面站预筛选够用了但实时追踪还是建议跑在 PC 端把低功耗设备当成远程观察哨用。树莓派 5 性能更强跑 YOLOv5s 的量化模型实测能到接近 20 FPS配合cv2.VideoWriter推流可以做一个无屏幕的便携检测站。以上这些是我在拆这套包时顺手验证过的路径。从那以后我每次拿到带权重的源码包都会强制走一遍“先查环境版本 → 再跑推理 → 再看训练日志”的流程权重能加载、推理有框、日志有曲线才敢说这个包真的能用。这套流程也希望对你有用希望帮到你。本文还有配套的精品资源点击获取
分享:

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

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