无人机技术的快速发展和人工智能的结合,赋予了无人机更强的感知能力与智能化功能。本文详细阐述了如何基于树莓派5与PX4飞控开发一套完整的视觉识别无人机系统,包括模型训练、代码实现、硬件部署和运行调试,帮助开发者快速构建功能完善的智能无人机。
视觉识别无人机的开发过程和软硬件架构设计(以 PX4 飞控和树莓派 5 为例)概述:
硬件:
软件:
+--------------------------------+ | 摄像头(USB/CSI接口) | +--------------------------------+ │ │ +--------------------------------+ | 树莓派 5 | | - 摄像头数据采集 | | - 图像处理与目标检测 | | - 决策计算(路径规划等) | | - MAVLink 数据发送 | +--------------------------------+ │ │ UART/Wi-Fi +--------------------------------+ | PX4 飞控(Pixhawk 4等) | | - 姿态稳定控制 | | - 电机控制 | | - 数据接收与飞行任务执行 | +--------------------------------+ │ │ PWM 信号 +--------------------------------+ | 电机+螺旋桨系统 | +--------------------------------+ │ │ 电池 +--------------------------------+ | 电源管理单元(PMU) | +--------------------------------+
+-----------------------------------+ | 树莓派(边缘计算) | | - 摄像头驱动 | | - OpenCV 图像处理库 | | - 目标检测算法(TensorFlow Lite) | | - 数据传输模块(MAVLink) | +-----------------------------------+ │ │ UART/Wi-Fi +-----------------------------------+ | PX4 飞控固件 | | - 姿态控制(PID) | | - 飞行模式(Offboard/Auto) | | - MAVLink 接口 | +-----------------------------------+
视觉算法
通信协议
实时性保障
飞行模式
安全性设计
训练模型需要一个性能较强的计算环境,例如支持 GPU 加速的深度学习训练服务器或云端平台。推荐配置:
安装 PyTorch 和 YOLOv8:
# 安装 PyTorch 和 GPU 支持 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装 Ultralytics 的 YOLOv8 pip install ultralytics
YOLOv8 采用的训练数据格式为 YOLO 格式,包括:
<class_id> <x_center> <y_center> <width> <height>
<class_id>:类别编号,从 0 开始。<x_center> 和 <y_center>:归一化后的目标框中心点坐标(范围为 0~1)。<width> 和 <height>:归一化后的目标框宽度和高度。将数据集整理为以下目录结构:
dataset/ ├── images/ │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 ├── labels/ │ ├── train/ # 训练集标签 │ ├── val/ # 验证集标签 ├── data.yaml # 数据集配置文件
data.yaml 配置文件内容示例:
train: dataset/images/train val: dataset/images/val nc: 2 # 类别数量 names: ['class1', 'class2'] # 类别名称
使用 YOLOv8 提供的命令行工具进行训练:
yolo task=detect mode=train model=yolov8n.pt data=dataset/data.yaml epochs=100 imgsz=640
model=yolov8n.pt:指定模型权重(nano 版,轻量化)。data=dataset/data.yaml:数据集配置文件路径。epochs=100:训练轮数。imgsz=640:输入图像尺寸。训练完成后,权重文件将保存在 runs/detect/train/weights/best.pt。
将训练好的 PyTorch 模型转换为轻量化模型(如 ONNX 或 TensorRT 格式)。
安装 ONNX 支持库
pip install onnx onnx-simplifier
转换模型为 ONNX 格式
from ultralytics import YOLO # 加载模型 model = YOLO('runs/detect/train/weights/best.pt') # 导出为 ONNX 格式 model.export(format='onnx')
优化 ONNX 模型
使用 ONNX-Simplifier 优化模型:
python -m onnxsim model.onnx model_simplified.onnx
在树莓派 5 上安装必要的依赖并部署模型:
安装依赖库
sudo apt update && sudo apt install -y libopencv-dev pip install numpy onnxruntime opencv-python
部署模型文件
将 model_simplified.onnx 上传到树莓派(通过 SCP 或 U 盘)。
以下为模型推理的 Python 实现:
import cv2 import numpy as np import onnxruntime as ort # 加载 ONNX 模型 model_path = 'model_simplified.onnx' #我们训练的模型
session = ort.InferenceSession(model_path) # 输入大小 input_shape = (640, 640) # 加载摄像头 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break # 预处理:调整大小并归一化 input_image = cv2.resize(frame, input_shape) input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB) input_image = input_image.astype(np.float32) / 255.0 input_image = np.transpose(input_image, (2, 0, 1)) # HWC to CHW input_image = np.expand_dims(input_image, axis=0) # Add batch dimension # 推理 outputs = session.run(None, {'images': input_image})[0] # 后处理:绘制检测框 for det in outputs: x1, y1, x2, y2, conf, class_id = det if conf > 0.5: # 置信度阈值 cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.putText(frame, f'Class {int(class_id)}: {conf:.2f}', (int(x1), int(y1) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) # 显示 cv2.imshow("Detection", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
输入
(640, 640)(根据训练时的输入尺寸调整)。输出
(x1, y1, x2, y2) 坐标、置信度和类别编号。接着以树莓派 5 上摄像头对场景进行扫描识别并在识别到指定目标后与 PX4 飞控通信,然后飞到目标上方这样的一个简单的任务来详细描述具体的过程。
树莓派 5 通过 CSI 接口或 USB 接口连接摄像头。
cv2.VideoCapture 获取实时视频流。import cv2 import numpy as np import onnxruntime as ort # 加载模型 model_path = 'model_simplified.onnx' session = ort.InferenceSession(model_path) input_name = session.get_inputs()[0].name input_shape = session.get_inputs()[0].shape # 模型输入形状 (1, 3, 640, 640) # 摄像头初始化 cap = cv2.VideoCapture(0) # 0 表示默认摄像头 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) def preprocess(frame): """将帧处理为模型输入格式""" input_image = cv2.resize(frame, (input_shape[2], input_shape[3])) input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB) input_image = input_image.astype(np.float32) / 255.0 input_image = np.transpose(input_image, (2, 0, 1)) # HWC to CHW input_image = np.expand_dims(input_image, axis=0) # 添加批次维度 return input_image def postprocess(detections, frame): """解析模型输出并绘制检测结果""" height, width, _ = frame.shape for det in detections: x1, y1, x2, y2, conf, class_id = det if conf > 0.5: # 设置置信度阈值 # 将归一化坐标转换为像素坐标 x1, y1, x2, y2 = int(x1 * width), int(y1 * height), int(x2 * width), int(y2 * height) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, f'Class {int(class_id)}: {conf:.2f}', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) return frame while True: ret, frame = cap.read() if not ret: break # 图像预处理 input_image = preprocess(frame) # 推理 outputs = session.run(None, {input_name: input_image})[0] # 假设输出在第一个 tensor # 后处理并显示结果 processed_frame = postprocess(outputs, frame) cv2.imshow("Detection", processed_frame) if cv2.waitKey(1) & 0xFF == ord('q'): # 按 'q' 键退出 break cap.release() cv2.destroyAllWindows()
树莓派 5 和 PX4 飞控通过 MAVLink 协议 通信。可以使用 pymavlink 库发送和接收控制指令。
以下为检测到目标后,向 PX4 发送飞行指令的实现:
from pymavlink import mavutil # 初始化 MAVLink 连接 connection = mavutil.mavlink_connection('/dev/serial0', baud=57600) # UART 连接 connection.wait_heartbeat() # 等待飞控心跳包 def send_position_target(x, y, z, vx=0, vy=0, vz=0): """发送位置目标指令(Offboard 模式)""" connection.mav.set_position_target_local_ned_send( 0, # 时间戳 connection.target_system, connection.target_component, mavutil.mavlink.MAV_FRAME_LOCAL_NED, 0b110111111000, # 控制掩码(只控制位置和速度) x, y, -z, # 目标位置 (NED 坐标) vx, vy, vz, # 目标速度 0, 0, 0, # 加速度 0, 0 # 偏航角和角速度 ) def calculate_position(offset_x, offset_y, current_altitude): """根据图像目标计算飞行器的移动目标""" # 假设摄像头视野角度和无人机距离目标高度已知 fov = 60 # 摄像头水平视野角度(度) image_width = 640 image_height = 480 fov_per_pixel = fov / image_width # 每像素对应的视野角度 # 计算目标相对于中心的偏移角度 angle_x = offset_x * fov_per_pixel angle_y = offset_y * fov_per_pixel # 根据偏移角度和当前高度,计算目标相对位置 delta_x = current_altitude * np.tan(np.radians(angle_x)) delta_y = current_altitude * np.tan(np.radians(angle_y)) return delta_x, delta_y # 检测到目标时,计算位置并发送指令 if target_detected: offset_x = detected_x - image_width / 2 offset_y = detected_y - image_height / 2 target_x, target_y = calculate_position(offset_x, offset_y, current_altitude=10) # 假设当前高度 10 米 send_position_target(target_x, target_y, z=10)
摄像头扫描
计算目标偏移
发送飞行指令
开发环境准备
raspistill 或 libcamera 测试摄像头。硬件连接
/boot/config.txt,添加或解开以下行:enable_uart=1
sudo raspi-config,在 Interface Options -> Serial Port 中禁用登录但启用串口硬件。依赖库安装
在树莓派上安装必要的依赖库:
sudo apt update sudo apt install -y python3-pip python3-opencv libopencv-dev pip3 install numpy onnxruntime pymavlink
将 Python 脚本和 ONNX 模型文件上传到树莓派上的指定目录(例如 /home/pi/drone_project)。
scp main.py model_simplified.onnx pi@<树莓派IP地址>:/home/pi/drone_project/
可以使用 pyinstaller 将 Python 脚本打包为可执行文件,以减少运行时依赖:
pip install pyinstaller pyinstaller --onefile main.py
编译成功后,生成的可执行文件会保存在 dist/ 目录下(例如 /home/pi/drone_project/dist/main)。
将编译后的文件上传到树莓派,或直接在树莓派上使用 pyinstaller 进行编译。
在树莓派中,通过命令行运行代码以测试:
cd /home/pi/drone_project python3 main.py # 如果使用了 pyinstaller 打包: ./dist/main
为了在无人机上实现自动化部署,可以将程序配置为开机自启动:
在树莓派上创建服务文件:
sudo nano /etc/systemd/system/drone_ai.service
文件内容如下:
[Unit] Description=Drone AI Service After=network.target [Service] ExecStart=/usr/bin/python3 /home/pi/drone_project/main.py Restart=always User=pi WorkingDirectory=/home/pi/drone_project StandardOutput=inherit StandardError=inherit [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl enable drone_ai.service sudo systemctl start drone_ai.service
通过以下命令查看服务状态:
sudo systemctl status drone_ai.service
如果一切正常,程序将在树莓派开机时自动运行。
性能优化
htop 检查 CPU 和内存占用情况。日志与调试
logging 模块)以记录运行信息。/var/log/syslog 中查看程序输出日志。将无人机飞控切换到 Offboard 模式,运行程序,测试目标检测和飞行指令执行是否正确。
使用 PX4 仿真环境(如 Gazebo 或 SITL)验证目标识别和飞行控制逻辑,确保安全。
通过以上步骤,您的 Python 项目可成功部署到树莓派 5 上,并在真机中执行目标检测和无人机飞行控制任务。
当然,除了树莓派5,还有其他的嵌入式平台可以作为智能无人机的大脑,然后3D打印出无人机框架和外壳,就可以实现自己的无人机了
0 评论