实时视频边缘化处理
【EASY EAI Nano开源套件试用体验】3. OpenCV图像处理开发测试 大信(QQ:8125036)
电子发烧友和灵眸科技推出EASY EAI Nano 开发板的试用。该开发板是基于Rockchip 的RV1126 AIoT处理器开发,采用四核32位Cortex®-A7架构,集成2.0 TOPs AI算力的NPU,可以作为为工业嵌入式处理器,开发板还支持多路视频编解码,有丰富的扩展接口,能够广泛适用物联网边缘计算以及智能应用,如人脸闸机、车载录像、安防监控等方面 本次就尝试研究测试该开发板在图像处理和多媒体方面的性能,本次以开发板带的摄像头作为输入,通过OpenCV对图像进行实时处理,并将处理后的内容输出到屏幕上,同时保存处理后的图片文件。
一、EASY EAInano 的多媒体组件
通过阅读在线文档,了解到EASY EAI nano 具备丰富的多媒体能力,开发板也有双目摄像头与显示屏,为多媒体应用开发测试提供了便利。 EASY EAI nano的流媒体(StreamingMedia)组件能将音视频内容采集后,以流的方式在网络中分段传送,实现在网络上实时传输。 能够处理音频流、视频流、文本流、图像流、动画流等。每一种流媒体,都有其独特的编码格式。多媒体文件,则是一个把多种流媒体组装起来的文件,这种组装多种不同流媒体编码的格式则被称为封装格式。其支持多种格式,比如: 封装格式:avi、rmvb、mp4、mp3、flv、mkv、wmv等。 该开发平台也具有多种的音视频的编码格式:视频编码格式(H.264、H.265等),音频格式(AAC、mp3等)。 其多媒体系统架构如下:
EASY EAI nano支持把当前编码器输入的图片格式为YUV420SP_NV12,YUV数据格式由三种数据构成:灰度值数据(Y)、蓝色分量数据(U),红色分量数据(V)。数据内容如下所示。
在EASY EAInano开发板上,使用rkMedia SDK来调用这些多媒体功能。而easy-eai又对其进行了再次的封装,形成了easyeai 库,该库简化了rkmedia的接口调用的繁琐方式,可以很简单的完成摄像头图像的获取,视频编码,解码,显示等操作。给测试带来的很大的便利,不过easyeai库并没有提供源码。对想深入研究的开发者来说,还需充学习rkMedia SDK,才能更好的挖掘硬件操作的细节。
二、图像采集测试
先从https://github.com/EASY-EAI/EASY-EAI-Toolkit-C-Demo.git 这里下载EASY-EAI-Tookit-DEMO的测试工程源码。
进入到 peripheral-camera工程 打开工程查看test-mipi-rgb.c源码:
源码如下:
- #include
- #include
- #include
- #include
- #define CAMERA_WIDTH 720
- #define CAMERA_HEIGHT 1280
- #define IMGRAtiO 3
- #define IMAGE_SIZE (CAMERA_WIDTH*CAMERA_HEIGHT*IMGRATIO)
- int main()
- {
- char *pbuf = NULL;
- int ret = 0;
- int skip = 0;
- FILE *fp = NULL;
- ret = rgbcamera_init(CAMERA_WIDTH, CAMERA_HEIGHT, 90);
- if (ret) {
- printf("error: %s, %dn", __func__, __LINE__);
- goto exit3;
- }
- //rgbcamera_set_format(RK_FORMAT_RGB_888);
- pbuf = (char *)malloc(IMAGE_SIZE);
- if (!pbuf) {
- printf("error: %s, %dn", __func__, __LINE__);
- ret = -1;
- goto exit2;
- }
- //跳过前10帧
- skip = 10;
- while(skip--) {
- ret = rgbcamera_getframe(pbuf);
- if (ret) {
- printf("error: %s, %dn", __func__, __LINE__);
- goto exit1;
- }
- }
- /* tips: 可以在Ubuntu下用mplayer播放录制图像
- * adb pull /tmp/photo
- * mplayer -demuxer rawvideo -rawvideo w=720:h=1280:format=bgr24 photo -loop 0
- */
- fp = fopen("./photo_csi_cam.bgr", "w");
- if (!fp) {
- printf("error: %s, %dn", __func__, __LINE__);
- ret = -1;
- goto exit2;
- }
- fwrite(pbuf, 1, IMAGE_SIZE, fp);
- fclose(fp);
- exit1:
- free(pbuf);
- pbuf = NULL;
- exit2:
- rgbcamera_exit();
- exit3:
- return ret;
- }
复制代码
源码非常简洁,其视频采集主要函数有这几个: int rgbcamera_init(intwidth, int height, int rot); 这个是对MIPICSI的双目摄像头中的可见光摄像头进行初始化,并设置采集图像的宽高,以及设置图像为旋转90度的方式。 void rgbcamera_set_format(intformat); 这个函数是对摄像头采集的数据格式进行设置,设置摄像头采集输出RK_FORMAT_YCbCr_420_SP ,或RK_FORMAT_BGR_888格式,即Yuyv 格式与RGB图像格式。一般视频应用时,使用yuyv格式,图片采用 RGB格式。 intrgbcamera_getframe(pbuf); 这个函数是对摄像头进行采集一帧数据,采集到的数据存放在pbuf指向的地址里,这里需要提前分配好pbuf的空间。 地址空间的计算为 size(byte)= 宽 x 高 x 3 . 最后使用这个函数退出采集: void rgbcamera_exit(void); 这样就能得到了mipi摄像头采集的一帧数据,采集的数据数据可以保存到文件,通过一些观看软件查看其内容。再通过连续的采集,就完成实时的图片采集了。 通过编译该例子,并在板上运行,先进入该工程代码,进行cmake 配置编译。
再进行编译:
传到板上,并且运行:
编译成功,传到板子上运行,获得了采集的图片文件,在PC上观看如下:
图像非常清晰,只是这里颜色 R与B反了,是因为摄像头默认采集的是BGR 格式,而这个播放软件只支持 RGB 格式。当设置为RK_FORMAT_RGB_888,则输出了正常演示的图片:
三、图像显示测试
同样在上面的Demo工程目录下,进入到peripheral-display 工程 打开工程查看test-display.c源码:
可见其中控制显示的主要函数如下: int disp_init(int width,int height); 显示输出化,执行显示屏幕的宽高,默认格式RGB888 void disp_commit(void*ptr, int data_len); 提交显示,即显示一幅图片在屏幕上。 void disp_exit(void); 退出显示时调用释放资源。 同样,进入该目录,对代码略修改一下,使充命令行传入要显示的rgb图片文件,并进入build目录进行cmake配置,再编译:
板上运行:
屏幕上成功的显示出mipi摄像头采集的视频画面和文件:
四、OpenCV 开发测试
OpenCV是图形图像处理常用的一个工具,它提供了非常丰富的视觉处理算法,它大部分以C语言编写,并且有开源的特性,一般不需要添加新的外部支持也可以完整的编译链接生成执行程序,所以常用它来做算法的移植,而OpenCV的代码经过适当改写可以正常的运行在DSP系统和 ARM嵌入式系统中。因此OpenCV常作为图像处理研究的工具。
这里先从OpenCV源码工程的例程库,找到一个OpenCV的例程drawing.c ,如下:
这个例程是创建一幅空白的图像,通过各种画图函数,向图像内画线,方框,园等图案。
再写一个简单的Makefile,直接编译,上传板上运行:
板上直接运行,结果如下:
板上运行结果出现了程序崩溃,看来直接opencv程序是无法正确运行的。
经过对代码的分析研究,发现EASY-EAI Nano开发板虽然有opencv的运行库,但是它并没有实现显示,键盘输入输出等函数的实现,导致一般opencv程序在该开发板上执行一些函数时,会导致崩溃。
主要的崩溃凶手之一是capture();imshow(wndname, image);和waitKey(char);这几个函数。推测原因是这几个函数在该开发板上不支持!
解决方法是把代码中所有使用这两个函数的地方去掉,使用上面的图像采集和图像显示的接口来和OpenCV对接,即通过RkMedia SDK和OpenCV对接,完成opencv中的图像采集输入与输出显示。
方法就是把OPenCV的Mat图像矩阵中的数据复制到easyeai显示所指向的内存区域里,然后调用esayeai的显示函数来显示opencv的图片内容。
经过研究,实现方式如下:image 为Mat对象
然后把修改过的代码,再重新编译,板上运行,终于得到了正确的结果,并在屏幕上显示了opencv绘画的图像正确输出:
查看输出保存的图像文件 drawing_01.jpg,显示如下:
同样,再测试对读入图片显示和叠加内容后输出,也能正确输出:
继续把输入改为从摄像头输入,并通过opencv保存图像文件,也都得到正确的图片文件。
把摄像头输入改为红外摄像头输入,则通过OpenCV保存抓取的图像文件获得如下的灰度:
五、OpenCV 图像算法测试 在建立好OpenCV开发基础上,就可以进一步增加OpenCV的各种算法,对图像进行处理,并把处理后的图像输出到屏幕上和文件里。
在网上找到一些OpenCV的图像处理的滤镜算发,把它加入到上面的工程中去,即读入一张图后,在通过图像处理算法处理图像,再把新生成的图像输出到屏幕上来。
这些算法代码都很小,很容易加进来,这样可以评估各算法在板上运行效率。OpenCV主要常用的图像处理算法有这些:
- opencv滤镜-实现晕影vignetting效果
- opencv滤镜-图像灰度化
- opencv滤镜-二值化实现黑白滤镜
- opencv滤镜-反向滤镜
- opencv滤镜-去色滤镜
- opencv滤镜-单色滤镜
- opencv滤镜-怀旧滤镜
- opencv滤镜-熔铸滤镜
- opencv滤镜-冰冻滤镜
- opencv滤镜-连环画滤镜
- opencv滤镜-浮雕雕刻特效
- opencv滤镜-素描
- opencv滤镜-羽化特效
每个算法可以做成一个函数,代码如下:
板上运行输出都得到正确的输出,因为测试图比较多,这里随便挑几个放出来看一下:
原图:
素描效果:
边缘扫描效果:
浮雕效果:
立体效果:
图像白平衡效果:
六、OpenCV 之红外伪彩变换
有了上面开发测试的基础,可以进一步,利用opencv的图像处理功能,来开发一个好玩的东西:
这就是红外像机,开发板带有双目摄像头,其中一个为红外像机,但从红外像机抓出的图示标识红外温度的灰度图,跟我们常见的红外像机并不一样,这里就需要用到一个灰度转彩色的变换的图像处理。
红外图像在一定程度上反映了环境中物体的温度变化——我们可以认为较暗的图像区域表示的是温度较低的区域(蓝色来表示),更加明亮的区域认为是温度较高的区域(红色来表示),进而将灰度图转变为彩色数据便于人类的视觉系统进行可视化。用伪彩色更好地显示数据的其他例子是高度、压力、密度、湿度等等。
OpenCV定义了12种colormap(色度图),可以应用于8位的灰度图像,使用函数applyColorMap产生伪彩色图像。
applyColorMap定义
1 voidapplyColorMap(InputArray src, OutputArray dst, int colormap);
2 //InputArray src: 输入原始图像(只支持8位灰度图像)
3 //OutputArray dst: 输出结果伪彩色图像
4 // intcolormap: 色度图的种类
applyColorMap用法
1 using namespacecv;
2 Matim_gray = rgb2mat(buff);
3 Matim_color;
4applyColorMap(im_gray, im_color, COLORMAP_JET);
下面是OpenCV的colormap(色度图)的视觉表示和COLORMAP_*的数值,左边的颜色模式表示较低的灰度值,右边的则表示较高的灰度值。
程序的流程是,对每一帧图像做如下的处理: 取红外摄像头数据 -> 转变为Mat矩阵->applyColorMap ->再变换为rgb数据->送显示器显示
这样不断循环上面的过程,就完成了伪彩红外像机的效果,下面是实现程序的编译,上传和执行:
板上执行:
最后屏幕上输出的效果:
并录制了一段测试效果的视频,见文章附带视频。总体测试,每秒大概为4帧左右,卡顿明显。经过分析,主要影响速度瓶颈在图像两次RGB到MAT矩阵的变换上,如果取消显示,并且使用固定的图片来做伪彩变换,速度每秒可达20帧以上。
以后可以考虑直接使用RkMedia来直接操作图像数据,并且使用OpenCV直接操作共享图像数据的方式来进行变换,省去图像来回变换的过程,这样速度会快很多。
七、OpenCV开发测试总结
经过在EASY EAI nano开发板上进行OpenCV的测试开发,验证了在该开发板上使用OpenCV进行图形图像处理的过程。虽然该开发板所带的OpenCV部分与硬件相关函数存在问题,主要是显示函数。但通过RkMedia的库,可以曲线的完成图像的采集和显示。
虽然通过这些接口可以完成OpenCV的输入输出,但也造成了效率的损失。但作为研究算法的目的,已经可以完成大部分的实验目的。概括而言该开发板能够很好的支持OpenCV的应用开发。
红外摄像头伪彩处理
|