RK3568-USB摄像头实时AI物品识别
为了更直观的体验RK3568的AI算力,将AI识别例程与摄像头功能结合起来,对摄像头的每一帧图像进行物品识别,这里使用的是RK提供的SSD模型。
SSD,全称为Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一种目标检测算法,属于一阶段One Stage方法,SSD 模型利用不同尺度的特征图进行目标的检测,其模型结构图如下:

SSD具有如下主要特点:
从YOLO中继承了将detection转化为regression的思路,同时一次即可完成网络训练
基于Faster RCNN中的anchor,提出了相似的prior box
加入基于特征金字塔(Pyramidal Feature Hierarchy)的检测方式,相当于半个FPN思路
SSD网络结构图如下:

其算法步骤为:
将图像输入预训练好的分类网络(基于VGG16-Atrous)得到不同大小的特征映射
分别提取Conv4_3、Conv7、Conv8_2、Conv9_2、Conv10_2、Conv11_2层的特征映射feature map,在每个特征映射的每个点构造6个不同大小尺度的bounding box,进行检测和分类来生成一些列bounding box
采用NMS处理不同特征映射的bounding box,删掉部分重叠或者不正确的bounding box,得到最终的检测框
OK3568-C开发板中自带了已训练好的AI模型,位于/userdata/model目录下的ssd_inception_v2.rknn,我们直接用就可以了。
2 USB摄像头实现物品识别代码
先来看下整个代码的项目结构,然后再来分别介绍各个功能模块。
imageutil.h:图像类型转换相关函数
myvideosourceface.cpp/h:用于USB摄像头图像显示
qtcamera.cpp/h:qt界面
rknn_ssd_process.cpp/h:用于SSD模型进行AI物品识别的接口函数
rknn_ssd.cpp/h:SSD模型相关函数

3 按帧获取USB摄像头图像
Qt读取并显示USB摄像头,需要3个基本元素:
QCamera:它是用于读取摄像头视频信号的接口函数
QCameraInfo:它提供相机设备的常规信息,可以用来查询系统上当前可用的相机设备
QCameraViewfinder:它提供了一个相机取景器的小部,该类继承于QVideoWidget类,用于显示多媒体类提供的视频
3.1 USB相机获取图像
查找USB相机
3.2 改为自己的Viewfinder
上面的USB摄像头显示程序,使用的是Qt的QCameraViewfinder用来显示摄像头图像,为了能获取到每一帧的图像,可以自己实现一个Viewfinder,然后在m_camera->setViewfinder时设置为自己的,并添加槽函数rcvFrame,当获取到一帧图像时,会触发此函数。
4 图像类型的转换与显示
4.1 QImage转Mat
Qt是QCamera创建的USB摄像头,获取到的图片格式是QImage类型,而使用OpenCV进行图像处理,需要转换为cv::Mat类型,转换的方式如下:
4.2 Mat转QImage
OpenCV进行图像处理完成后,比如进行AI物品识别完成,并将识别的信息标记到图像上后,需要再转成QImage的类型用于在Qt中显示出来,转换的方式如下:
4.3 QImage转QPixmap
QImage在Qt中还不能直接显示出来,还需要再转为QPixmap类型,转换的方式如下:
4.4 图像的显示
这里创建一个QLabel用于显示图像,调用setPixmap方法即可将图像显示出来,最后的adjustSize用来自动调整大小。
5 RKNN例程移植
飞凌OK3568-C开发板资料中,自带了ssd模型的测试程序,代码位置如下,ssd的测试代码是这3个文件:

测试代码,需要在执行时,输入模型的目录位置和测试图片的位置,AI物品识别之后会产生一个输出图片,需要再使用图片查看器查看结果。
为了方便功能的调用,这里将fltest_opencv_rknn_ssd_main.cc改写为rknn_ssd_process.cpp,并将具体功能进行拆分,封装为C++的形式。
5.1 按功能封装为C++形式
自己封装的RknnSsdModel类定义:
5.1.1 RKNN初始化
主要功能是根据传入的rknn模型进行相关的初始化
5.1.2 RKNN运行
传入一张Mat格式的图片(一帧视频图像),经过AI识别,并将识别的信息标注到图片上后,将识别结果也以Mat格式传出:
5.2 AI识别调用
OK3568-C开发板中自带了已训练好的AI模型,位于/userdata/model目录下的ssd_inception_v2.rknn,在程序初始化时需要用到。

AI识别的代码逻辑为:先在qtCamera初始化时调用RKNN的初始化,然后打开USB摄像头,USB获取到每帧图像后, 调用DoRknnSsd进行AI物品识别,最后将识别的结果通过setPixmap方法展示出来
5.3 编译
需要注意下Qt工程的配置文件,要把opencv的一些库链接进去
qcamera.pri
qcamera.pro
最后的编译脚本还和之前的一样:
6 总结
本篇介绍了在飞凌OK3568-C开发板中,外接USB摄像头,利用Qt和RKNN进行AI物品识别,通过已训练好的SSD模型,进行摄像头画面的实时AI物品检查的代码实现原理。
