一.概览
本人虽然是电子信息技术专业出身,在毕业后从事的是偏软件的工作,大多数是PC软件的开发,但一直以来,闲暇时间会利用STM32做些小的作品。对于RT-Thread这国内的物联网操作系统,其实早有耳闻,期间也参加过深圳的一次RT-Thread线下交流活动,所以对于RT-Thread是有所了解而未实际应用的程度。
借着此次RT-Thread大赛的机会,我想将PC的一些图像处理和图像识别算法放到art-pi试跑一下看看效果如何,所以本次参赛将会使用art-pi获取OV7670的图像来做像处理和图像识别。
二.开发环境
硬件: PC、ART-PI、OV7670、RGB_LCD
RT-Thread版本: rt-thread4 .0.3,art-pi adk 1.1.0
开发工具及版本: 立创EDA,RT-Studio,SecureCRT
三.RT-Thread使用情况概述
线程: 创建图像处理线程用于通过DCMI获取OV7670的图像,图像处理后完显示在LCD上
信号量: 用于DCMI图像获取,当捕捉完一帧图像后,释放信号量给图像处理线程。
驱动: 使用了drv_dcmi驱动并参考drv_ov2640移植drv_ov7670驱动
四.实现功能展示
通过摄像头采集图像进行图像识别,然后将结果显示在LCD屏幕上。
五.硬件框架
本次的硬件核心由ART-PI、OV7670、LCD三部分组成:
ART-PI:stm32H750作为控制核心部分,采集图像源数据、处理图像源生成处理结果、将处理结果送到LCD显示
OV7670:作为图像源,提供320*240的RGB565图像
LCD:实时显示图像源图像和显示处理结果
六.软件流程图
- 硬件初始化:时钟、I2C、DCMI、SDRAM、LTDC
- 进入图像处理线程,启动拍照并等待拍照完成信号量
- 完成拍照释放拍照完成信号量
- 得到图像后,进行图像处理与图像识别
- 将图像识别结果在LCD上显示
- 回到步骤2
七.图像识别功能介绍
通过DCMI驱动获取OV7670的分辨率为320240的RGB565原始图像。RGB565每个像素使用用下图的方式存储,每个像素占用2个字节。所以每帧320240的图像所需内存为3202402=153600字节。
实际上,我们在这次项目中并不需要使用到彩色特征,所以先将RGB565转换为灰色度。灰度图其实就是每个像素占用一字节,用0-255值来形容一个像素的灰度值。因此320240所占用的内存为76800字节。
RGB565转灰度图公式如下: Gray = R0.299 + G0.587 + B0.114
提取的灰度图后,我们还需要再进行一次二值化处理,因此设定一个阈值,当灰色像素大于这个阈值我们将它改为255,低于这个值变成0。这样就得到一帧只有0和225值的图像。
得到二值化图像后,我们便可以寻找要识别物体了。在此使用九宫格的方式提取连通分量,原理其实很简单,就是在九宫格里寻找连在一起的像素,如果能找到便将该像素便将该像素的坐标(位于X行,y列)写入到链表里。如此循环,直到找完所有像素。
完成连通分量的提取后便是特征提取了,我们还是采用九宫格分割法,将取得的图像平均分割为9个区域,再计算9个区域中值为255像素的个数。通过这一步算法,我们得到了9组特征数据。
本次用了两种特征提取方式:
- 通过水平与垂直方向的穿越数找出部分数字
以数字0和7为例,在1/2宽度处,0和7稳定的得到垂直穿越数是2.而在1/2高度,0的水平穿越数是2,7的水平穿越数是1.
- 在图像的水平和垂直的中间切分成四块,根据四个部分不同像素比例找出其他数字。以2和3为例 ,在右下角部分,3的每一行都会有像素点,而2会缺几行。因此2的像素更少从而区分2和3。
最终检测效果如下图:
原作者:林桂炯