1. 项目概述:基于QT+ESP32CAM+RK3566的嵌入式视觉识别系统
这个项目实现了一个完整的嵌入式视觉识别系统,通过ESP32CAM采集视频流,RK3566开发板(泰山派)接收并处理视频数据,使用YOLOv11n模型进行实时物体识别,最后通过QT界面展示识别结果。整套系统涉及硬件选型、嵌入式开发、模型转换和图形界面编程等多个技术领域,是典型的边缘计算应用场景。
我在实际开发中发现,这种组合方案特别适合需要低功耗、实时性要求较高的场景,比如智能门禁、工业质检等。ESP32CAM作为低成本的图像采集终端,RK3566提供足够的算力运行轻量级YOLO模型,QT则提供了友好的交互界面。下面我将从硬件选型到软件实现的完整流程进行详细解析。
2. 硬件平台搭建与配置
2.1 ESP32CAM模块配置
ESP32CAM是目前性价比极高的WiFi摄像头方案,集成了ESP32芯片和OV2640摄像头模块。我选择它主要考虑以下几点:
- 支持802.11 b/g/n WiFi协议
- 内置520KB SRAM和4MB PSRAM
- 支持JPEG格式图像输出
- 开发社区活跃,资料丰富
开发环境搭建步骤:
- 安装Arduino IDE(建议1.8.x版本)
- 添加ESP32开发板支持:
- 文件→首选项→附加开发板管理器网址
- 添加:
https://espressif.github.io/arduino-esp32/package_esp32_index.json - 工具→开发板→开发板管理器→搜索"esp32"安装
注意:国内用户可能会遇到下载失败的问题。我的经验是早上8点前下载成功率较高,或者使用手机热点。如果持续失败,可以手动下载开发板包,解压到Arduino的hardware目录下。
CameraWebServer示例修改要点:
cpp复制// 只保留AI Thinker型号的定义
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
// 修改WiFi配置
const char* ssid = "Your_WiFi_SSID";
const char* password = "Your_WiFi_Password";
// 视频流配置(建议保持默认)
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
上传程序后,需要断开IO0引脚的跳线帽,按复位键启动。在浏览器访问ESP32CAM的IP地址(串口会打印),点击"Start Stream"即可看到视频流。
2.2 RK3566(泰山派)开发板配置
泰山派RK3566是一款基于Rockchip RK3566处理器的开发板,主要特性:
- 四核Cortex-A55处理器
- 0.8TOPS NPU
- 支持4K视频解码
- 丰富的接口(HDMI、USB、GPIO等)
系统环境准备:
- 使用立创官方提供的Ubuntu 18.04镜像
- 解决apt被锁问题:
bash复制sudo rm /var/lib/apt/lists/lock sudo rm /var/cache/apt/archives/lock sudo rm /var/lib/dpkg/lock sudo dpkg --configure -a sudo apt update - 安装必要依赖:
bash复制sudo apt install -y qt5-default libopencv-dev cmake git
3. 模型转换与部署
3.1 YOLOv11n模型准备
YOLOv11n是YOLO系列中的轻量级模型,适合在嵌入式设备上运行。模型特点:
- 输入分辨率:640x640
- 参数量:约3.7M
- 支持80类COCO数据集物体识别
模型转换流程:
- 下载预训练的ONNX模型
- 安装rknn-toolkit2(建议2.3.2版本):
bash复制
pip install rknn-toolkit2==2.3.2 - 编写转换脚本(示例):
python复制from rknn.api import RKNN # 创建RKNN对象 rknn = RKNN() # 模型配置 rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rk3566') # 加载ONNX模型 ret = rknn.load_onnx(model='yolov11n.onnx') # 量化模型(提高推理速度) ret = rknn.build(do_quantization=True, dataset='./dataset.txt') # 导出RKNN模型 ret = rknn.export_rknn('./yolov11n.rknn')
提示:量化时需要准备约100-200张代表性图片,保存路径写入dataset.txt文件。量化能显著减小模型体积并提高推理速度。
3.2 模型性能优化技巧
在实际部署中,我发现以下几个优化点很关键:
- 输入尺寸调整:根据实际识别距离,可以适当减小输入分辨率(如320x320),速度可提升3-4倍
- 后处理优化:将NMS操作移到CPU执行,减少NPU负载
- 多线程处理:视频采集和模型推理使用不同线程,避免阻塞
4. QT应用程序开发
4.1 项目结构设计
采用模块化设计,便于维护和扩展:
code复制EdgeAI/
├── app/ # QT主界面和交互逻辑
├── libcore/ # 基础功能封装
├── libvideo/ # 视频流处理
├── libinfer/ # 模型推理接口
├── librecorder/ # 录像功能
├── libservice/ # 业务逻辑协调
├── models/ # 模型文件存放
├── thirdparty/ # 第三方库
└── build/ # 编译输出
4.2 关键功能实现
视频流获取:
cpp复制// 使用OpenCV获取ESP32CAM的MJPEG流
cv::VideoCapture cap("http://192.168.5.105:81/stream");
if(!cap.isOpened()) {
qDebug() << "无法打开视频流";
return;
}
// 读取帧
cv::Mat frame;
while(true) {
if(!cap.read(frame)) {
qDebug() << "读取帧失败";
break;
}
// ...处理帧数据
}
模型推理接口:
cpp复制// 初始化RKNN模型
int ret = rknn_init(&ctx, model_path, 0, 0, NULL);
if(ret < 0) {
qDebug() << "rknn_init失败:" << ret;
return false;
}
// 设置输入输出
rknn_input inputs[1];
inputs[0].index = 0;
inputs[0].type = RKNN_TENSOR_UINT8;
inputs[0].fmt = RKNN_TENSOR_NHWC;
inputs[0].buf = image_data; // 图像数据
inputs[0].size = input_size;
// 执行推理
ret = rknn_inputs_set(ctx, 1, inputs);
ret = rknn_run(ctx, nullptr);
ret = rknn_outputs_get(ctx, 1, outputs, nullptr);
结果显示:
cpp复制// 在QT中绘制识别结果
void VideoWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.drawImage(0, 0, displayImage);
// 绘制识别框
for(const auto& obj : detectedObjects) {
painter.setPen(QPen(Qt::green, 2));
painter.drawRect(obj.rect);
painter.drawText(obj.rect.topLeft(),
QString("%1 %2%").arg(obj.label).arg(obj.confidence*100, 0, 'f', 1));
}
}
5. 系统集成与调试
5.1 交叉编译环境搭建
由于RK3566性能有限,建议在x86主机上交叉编译:
- 安装交叉编译工具链:
bash复制sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - 配置QT交叉编译:
bash复制./configure -xplatform linux-aarch64-gnu-g++ \ -prefix /usr/local/qt5-arm \ -opensource -confirm-license make -j4 sudo make install - 在QT Creator中配置交叉编译工具链
5.2 常见问题解决
视频流延迟高:
- 降低ESP32CAM的分辨率(如QVGA)
- 减少JPEG压缩质量(CameraWebServer中可设置)
- 检查WiFi信号强度,确保稳定连接
模型推理速度慢:
- 使用
rknn_set_core_mask指定NPU核心 - 启用异步推理模式
- 减少同时检测的物体类别数量
QT界面卡顿:
- 使用QThread分离UI和计算任务
- 减少界面刷新频率(如30fps降为15fps)
- 关闭不必要的界面特效
6. 性能优化与扩展
经过实测,系统在以下配置下可以达到较好性能:
- ESP32CAM:320x240分辨率,15fps
- YOLOv11n:320x320输入,量化INT8
- RK3566:NPU全核心运行
性能指标:
- 端到端延迟:约200ms
- 识别准确率:COCO val2017上mAP@0.5约28.5%
- 系统功耗:约3.5W(含摄像头)
扩展建议:
- 添加本地存储功能,记录识别结果
- 实现多摄像头支持,扩大监控范围
- 集成MQTT协议,将结果上报云端
- 开发Android/iOS客户端,远程查看结果
在实际部署中,我发现环境光线对识别效果影响很大。建议在ESP32CAM上添加补光灯,或者增加自动曝光调整功能。另外,模型对小型物体识别效果一般,可以通过数据增强和微调来改善特定场景的识别率。