手把手教你用YOLO-v8.3:快速实现无人机自动避障(附完整代码)
手把手教你用YOLO-v8.3:快速实现无人机自动避障(附完整代码)
1. 为什么选择YOLO-v8.3做无人机避障?
想象一下,你的无人机正在空中飞行,前方突然出现一棵树或者一个行人。传统避障方案,比如超声波传感器,探测距离有限,而且容易受环境影响。激光雷达效果好,但价格贵、重量大,装在小型无人机上不现实。
这时候,基于摄像头的视觉方案就成了最佳选择。它成本低、重量轻,而且能“看懂”周围环境。在众多视觉算法里,YOLO(You Only Look Once)系列模型脱颖而出,因为它够快、够准。
YOLO-v8.3是Ultralytics公司维护的最新稳定版本之一。它最大的特点就是“快”和“小”。一个最小的YOLOv8n模型,只有几兆大小,在像树莓派、Jetson Nano这样的嵌入式设备上,也能跑出几十帧每秒的速度,完全能满足无人机实时避障的需求。
简单来说,用YOLO-v8.3做避障,就是用无人机的“眼睛”(摄像头)拍下前方画面,让模型快速识别出画面里的障碍物(比如人、车、树),然后告诉飞控系统:“前面有东西,快绕开!”
本文将带你从零开始,一步步搭建一个基于YOLO-v8.3的无人机避障视觉系统。我们会使用CSDN星图平台提供的“YOLO-V8”预置镜像,省去繁琐的环境配置,直接上手写代码、看效果。
2. 准备工作:快速搭建开发环境
自己从零搭建深度学习环境,光是安装各种依赖和配置CUDA就能劝退很多人。好在CSDN星图提供了开箱即用的“YOLO-V8”镜像,里面什么都装好了。
2.1 镜像里有什么?
这个镜像可以理解为一个已经配置好的“软件包”,你一键启动,就获得了一个完整的开发环境:
- 操作系统:Ubuntu 20.04,稳定且兼容性好。
- 深度学习框架:PyTorch 1.13 + CUDA 11.7,GPU加速必备。
- 核心工具包:
ultralytics==8.3.0:这是YOLO-v8的官方Python库,我们写代码全靠它。opencv-python:处理图像和视频的核心工具。numpy,matplotlib:科学计算和画图常用。
- 开发工具:预装了JupyterLab和SSH服务,方便你用不同方式写代码。
- 工作目录:镜像启动后,默认就在项目目录
/root/ultralytics下,里面已经有了一些示例。
2.2 两种方式开始编程
镜像提供了两种交互方式,你可以选自己喜欢的。
方式一:用JupyterLab(推荐给新手)
这种方式就像在用网页版的Python笔记本,可以边写代码边看结果,特别适合调试和可视化。
- 启动镜像后,在浏览器里打开JupyterLab的地址(通常是
http://你的服务器IP:8888)。 - 新建一个Python笔记本(Notebook)。
- 直接在里面写代码、运行,图像结果可以直接显示在网页上。
方式二:用SSH终端(适合自动化部署)
如果你习惯用命令行,或者想写一个脚本让无人机一直跑,可以用SSH。
- 用SSH工具(比如Xshell、MobaXterm或者系统自带的终端)连接到你的服务器。
- 登录后,输入
cd /root/ultralytics进入工作目录。 - 然后用
python your_script.py这样的命令来运行你的Python脚本。
3. 核心代码实战:让无人机“看见”障碍物
理论说再多,不如一行代码。下面我们就来写一个最核心的避障检测模块。这个模块的任务就是:读取摄像头画面,用YOLO-v8.3找出里面的障碍物,并判断是否需要避障。
3.1 第一步:加载模型与初始化
首先,我们创建一个Python脚本,比如叫 drone_obstacle_detection.py。
# drone_obstacle_detection.py
from ultralytics import YOLO
import cv2
import torch
# 1. 自动选择运行设备(有GPU就用GPU,没有就用CPU)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"使用设备: {device}")
# 2. 加载预训练的YOLOv8模型
# 这里我们使用最小的'nano'版本(yolov8n.pt),速度最快,适合无人机。
# 模型会自动从网上下载(如果本地没有的话)。
model = YOLO("yolov8n.pt").to(device)
# 3. 定义我们需要避开的障碍物类别
# YOLO默认能识别80类COCO数据集物体,我们只关心其中几类。
OBSTACLE_CLASSES = ['person', 'bicycle', 'car', 'motorcycle', 'bus', 'truck', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe']
# 注意:这个列表可以根据你的实际飞行环境增减。比如在公园飞,就要加上‘tree’。
def is_obstacle(class_name):
"""判断检测到的物体是否属于需要避开的障碍物"""
return class_name in OBSTACLE_CLASSES
代码解释:
YOLO("yolov8n.pt"):这行代码创建了一个YOLO模型对象。yolov8n.pt是预训练好的权重文件,n代表nano(最小),还有s(small),m(medium),l(large),x(xlarge) 等更大更准但更慢的版本。.to(device):把模型放到GPU或CPU上运行。OBSTACLE_CLASSES:这是我们自己定义的列表。YOLO能认很多物体,但无人机不需要避开所有东西(比如天空、云朵)。这里我们只把可能撞上的、有危险的物体算作障碍物。
3.2 第二步:编写核心检测与告警函数
接下来,我们写一个函数,它接收一帧图像,返回标注好的图像和是否有障碍物的判断。
def detect_and_alert(frame):
"""
对输入的一帧图像进行障碍物检测和告警判断。
参数:
frame: 摄像头捕捉到的一帧图像(numpy数组)
返回:
annotated_frame: 画上了检测框和标签的图像
need_avoidance: 布尔值,True表示需要执行避障动作
"""
# 使用模型进行推理
# conf=0.5: 只相信置信度高于50%的检测结果,减少误报。
# imgsz=640: 将图像缩放至640x640大小输入模型,这是速度和精度的平衡点。
results = model(frame, conf=0.5, imgsz=640)
# 获取第一个(也是唯一一个)结果的检测框信息
detections = results[0].boxes
need_avoidance = False
# 使用ultralytics内置方法,快速画出带标签的检测结果图
annotated_frame = results[0].plot()
# 如果没有检测到任何东西,直接返回
if detections is None:
return annotated_frame, need_avoidance
# 遍历所有检测到的物体
for box in detections:
# 获取物体类别ID和名称
cls_id = int(box.cls.cpu().numpy())
cls_name = model.names[cls_id]
# 判断它是不是我们需要避开的障碍物
if is_obstacle(cls_name):
confidence = float(box.conf.cpu().numpy()) # 检测置信度
# 获取物体边界框的坐标 (x1, y1, x2, y2)
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
# 关键判断:障碍物是否在飞行路径的“危险区域”?
# 我们假设无人机摄像头朝前,画面中心是飞行方向。
frame_center_x = frame.shape[1] / 2 # 图像宽度的一半
obstacle_center_x = (x1 + x2) / 2
# 定义“危险区域”:画面中心左右各30%的宽度范围
danger_zone_width = frame.shape[1] * 0.3
if abs(obstacle_center_x - frame_center_x) < danger_zone_width:
# 障碍物在危险区域内,触发避障告警
need_avoidance = True
print(f"[警告] 检测到障碍物: {cls_name}, 置信度: {confidence:.2f}, 位置: X中心={obstacle_center_x:.0f}")
# 在实际系统中,这里可以加上更复杂的逻辑,比如根据物体大小和距离判断紧急程度。
return annotated_frame, need_avoidance
代码解释:
model(frame, conf=0.5, imgsz=640):这是执行推理的核心。传入图像、置信度阈值和输入尺寸。results[0].plot():一个非常方便的函数,它自动把检测框、类别标签和置信度画在图像上,省去我们手动用OpenCV画图的麻烦。- 危险区域判断:这是避障逻辑的关键。我们只关心出现在画面正前方的障碍物。侧方的物体,即使检测到了,也暂时不处理,因为无人机可能只是从旁边飞过。这个
30%的阈值可以根据无人机视野和飞行速度调整。
3.3 第三步:连接视频源并运行主循环
最后,我们需要一个循环,不断地从摄像头获取画面,调用上面的函数,并显示结果。
# 主程序开始
if __name__ == "__main__":
# 设置视频源
# 方案1: 使用测试视频文件
# video_source = "test_flight.mp4"
# 方案2: 使用USB摄像头(通常为0)
# video_source = 0
# 方案3: 使用无人机的RTSP视频流(需要替换为你的无人机IP)
video_source = "rtsp://192.168.1.100:554/stream" # 示例地址,请替换
cap = cv2.VideoCapture(video_source)
if not cap.isOpened():
print("错误:无法打开视频源!")
exit()
print("开始检测,按 'q' 键退出...")
while cap.isOpened():
# 读取一帧
ret, frame = cap.read()
if not ret:
print("视频流结束或读取失败。")
break
# 执行障碍物检测
result_frame, need_avoid = detect_and_alert(frame)
# 如果需要避障,这里可以触发飞控指令
if need_avoid:
# 这里是和飞控通信的接口,需要根据你的飞控协议(如MAVLink)实现
# send_avoidance_command("HOVER_OR_TURN") # 伪代码
# 为了演示,我们在画面上显示一个红色的警告文字
cv2.putText(result_frame, "OBSTACLE AHEAD! AVOIDING...", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# 显示结果
cv2.imshow('Drone Obstacle Detection', result_frame)
# 按'q'键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
print("程序结束。")
运行与测试:
- 将上面的三段代码整合到一个
.py文件中。 - 在JupyterLab里新建一个单元格粘贴全部代码运行,或者通过SSH在终端执行
python drone_obstacle_detection.py。 - 首次运行时会自动下载
yolov8n.pt模型文件。 - 确保
video_source变量设置正确。你可以先用一个本地视频文件(如test_flight.mp4)或USB摄像头(0)测试。 - 如果一切正常,你会看到一个窗口,实时显示摄像头画面,并用框标出检测到的障碍物。当障碍物出现在画面中心区域时,控制台会打印警告,画面上也可能出现提示文字。
4. 从演示到真机:关键优化与注意事项
上面的代码是一个完整的演示原型。但要真正用到无人机上,还需要考虑更多工程问题。
4.1 性能优化:让检测更快
无人机的算力有限,我们必须榨干每一分性能。
- 模型量化:把模型从浮点数(FP32)转换成整数(INT8)格式,速度能提升2-3倍,精度损失很小。YOLO-v8.3支持导出为TensorRT引擎,这是NVIDIA设备上最快的运行方式。
# 在代码中导出为TensorRT引擎(需要提前安装TensorRT) model.export(format='engine', half=True) # half=True使用FP16精度,更快 # 然后加载导出的 .engine 文件进行推理 model = YOLO('yolov8n.engine') - 降低输入分辨率:代码里我们用的
imgsz=640。如果飞行环境简单,障碍物较大,可以尝试降到320,速度会快很多,但小物体可能就看不到了。 - 跳帧处理:如果帧率要求不是极高,可以每2帧或3帧处理一帧,用中间帧的检测结果来插值,能显著降低计算负载。
4.2 提升检测效果:让小物体和特殊环境更清晰
- 针对训练:用无人机在自己典型飞行环境(如园区、农田)拍摄的数据,对YOLO-v8.3进行微调(Fine-tuning),让它更熟悉你要避开的物体(比如特定的树木、电线)。
- 应对小物体:高空飞行时,远处的障碍物在图像上可能只有几十个像素。可以尝试使用更大的输入分辨率(如
imgsz=1280),或者选用YOLO-v8中带有“P2”或“P3”层的模型变体,它们对小目标更敏感。 - 应对光线天气:模型在夜间、雾天可能失效。可以考虑加装红外摄像头,或者训练时多加入不同天气、时段的数据。
4.3 系统集成:与飞控通信
代码中的 send_avoidance_command 是伪代码。真实集成需要:
- 选择通信协议:最常用的是MAVLink协议,它是无人机领域的通用语言。
- 定义指令:根据检测结果,生成具体的飞控指令。例如:
need_avoidance == True:发送MAV_CMD_NAV_GUIDED_ENABLE指令,让飞控进入“引导模式”,并给出一个偏航或爬升的设定点。- 更高级的,可以根据障碍物的位置和大小,计算出一个安全的绕行路径点。
- 注意延迟:从检测到发出指令,整个流程的延迟要尽可能低(最好<100ms)。使用高效的通信库(如
pymavlink)和优化代码逻辑至关重要。
5. 总结
通过本文,你已经掌握了使用YOLO-v8.3为无人机搭建视觉避障系统的核心流程:
- 环境准备:利用CSDN星图“YOLO-V8”镜像,秒搭开发环境。
- 核心开发:用不到100行Python代码,实现了视频流的实时障碍物检测与告警。
- 逻辑设计:学会了如何定义“障碍物”并判断其是否位于飞行路径的“危险区域”。
- 优化方向:了解了模型量化、分辨率调整等提升性能的方法,以及真机集成需要考虑的通信和延迟问题。
YOLO-v8.3的强大之处在于它平衡了速度、精度和易用性,让复杂的视觉感知任务变得触手可及。你可以基于本文的代码框架,进一步探索:
- 结合光流或双目视觉估算障碍物距离。
- 集成更高级的路径规划算法(如A*、D*)。
- 部署到真实的Jetson Nano或Orin NX等嵌入式AI设备上。
希望这篇手把手教程能成为你探索无人机智能视觉的起点。动手跑通代码,看着屏幕里的框随着障碍物移动,你会感受到AI赋予机器的“视觉”魅力。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)