【GD32450I-EVAL】+ 08图像识别-彩色物体跟踪
[复制链接]
本帖最后由 DDZZ669 于 2020-10-8 21:34 编辑
上篇文章【GD32450I-EVAL】+ 07摄像头全屏显示测试介绍了摄像头的使用,本篇利用摄像头采集的图像,进行简单的图像识别,借助EasyTrace彩色物体检测算法,实现对彩色物体的跟踪检测。
先看一下最终的效果:
1 EasyTrace简介
使用EasyTrace可以对单一颜色物体进行实时跟踪识别。
1.1 EasyTrace特点
1.代码只有300行,非常简单
2.识别一次只需要2至5毫秒,实时性强
3.只有1个API,使用方便
4.可配置”容错率“ ”迭代次数“等参数,可在”时间“实时性”“ ”准确度“ ”识别率“ ”误识率“ 之间寻找平衡点
1.2 使用举例
使用EasyTrace,首先需要自己提供一个指定位置的颜色读取函数:
//读取RBG格式颜色,唯一需要移植的函数
extern unsigned short GUI_ReadBit16Point(unsigned short x,unsigned short y);
然后使用如下3行就可以识别彩色物体了:
RESULT Resu;//识别的结果
TARGET_CONDI Condition={60,100,20,120,10,160,40,40,320,240};//识别的条件
Trace(&Condition,&Resu);//彩色物体检测API
识别条件与识别结果的结构体定义为:
typedef struct{
unsigned char H_MIN;//目标最小色调
unsigned char H_MAX;//目标最大色调
unsigned char S_MIN;//目标最小饱和度
unsigned char S_MAX;//目标最大饱和度
unsigned char L_MIN;//目标最小亮度
unsigned char L_MAX;//目标最大亮度
unsigned int WIDTH_MIN;//目标最小宽度
unsigned int HIGHT_MIN;//目标最小高度
unsigned int WIDTH_MAX;//目标最大宽度
unsigned int HIGHT_MAX;//目标最大高度
}TARGET_CONDI;//判定为的目标条件
typedef struct{
unsigned int x;//目标的x坐标
unsigned int y;//目标的y坐标
unsigned int w;//目标的宽度
unsigned int h;//目标的高度
}RESULT;//识别结果
//这里是图像搜索范围的定义
#define IMG_X 0 //图片x坐标
#define IMG_Y 0 //图片y坐标
#define IMG_W 480 //图片宽度
#define IMG_H 272 //图片高度
2 HSL色彩空间
EasyTrace识别彩色物体使用的是HSL色彩空间,即色调,饱和度,亮度。
色调(Hue)是色彩的基本属性,就是平常所说的颜色名称,如红色、黄色等。
饱和度(Saturation)是指色彩的纯度,越高色彩越纯,低则逐渐变灰。
亮度(Lightness)是指颜色的明亮程度。
关于色彩空间的具体细节,可以参考知乎问答: 色彩空间中的 HSL、HSV、HSB 有什么区别?
3 EasyTrace移植
3.1 GUI_ReadBit16Point函数
EasyTrace仅仅只有一个c文件和一个h文件,添加到自己的工程中即可,对于需要自己提供的“GUI_ReadBit16Point()"函数,资料例程中有一个lcd_point_get函数可以直接使用,封装一下即可:
//用于EasyTracer
unsigned short GUI_ReadBit16Point(unsigned short x,unsigned short y)
{
return lcd_point_get(x,y);
}
3.2 颜色阈值确定
本实验准备识别蓝色物体,但蓝色物体的HSL值如何确定呢,一种方法是网上查找蓝色对于的HSL的值,另一种方式是直接用摄像头拍摄要识别的物体,并通过程序将RGB转换为HSL,因为EasyTrace里有现成的颜色转换函数,我们改造一下来用:
while (1)
{
ReadColor(50,50,&testRGB);
RGBtoHSL(&testRGB,&testHSL);
printf("H=%d,S=%d,L=%d\r\n",testHSL.hue,testHSL.saturation,testHSL.luminance);
}
上面的我程序的主函数,摄像头采集的图像显示在LCD上,将要识别的物体放到摄像头前面,并使物体的中心大致位于(50,50)的位置,然后读取该位置的像素值,并转换为HSL,通过串口输出,这样,就能确定要识别的物体的HSL的大致范围了。
3.3 物体识别
然后,就是写一个识别与画矩形圈住物体的函数:
while (1)
{
if(Trace(&Condition1,&Resut)) //检测到了物体
{
if((lastResut.x!=Resut.x)&&(lastResut.y!=Resut.y)&&(lastResut.w!=Resut.w)&&(lastResut.h!=Resut.h))
{
lastResut.x = Resut.x;
lastResut.y = Resut.y;
lastResut.w = Resut.w;
lastResut.h = Resut.h;
lcd_layer_set(LCD_LAYER_FOREGROUND); //指定当前层为前景层(识别到物体后,在前景层画矩形块)
lcd_clear(LCD_COLOR_CYAN);//ARGB155模式下,LCD_COLOR_CYAN就是透明色
lcd_rectangle_line(lastResut.x-(lastResut.w/2),lastResut.y-(lastResut.h/2),lastResut.w,lastResut.h); //画矩形框
lcd_layer_set(LCD_LAYER_BACKGROUND); //再切换到背景层,用于物体识别(摄像头的图像在背景层显示)
}
delay_1ms(100);
}
else //没有检测到
{
delay_1ms(100);
if(10 == ++t) //等了1秒一直没检测到
{
t=0;
lcd_layer_set(LCD_LAYER_FOREGROUND);
lcd_clear(LCD_COLOR_CYAN); //清屏 (清除上次的矩形框块)
lcd_layer_set(LCD_LAYER_BACKGROUND);
}
}
}
这个程序中,摄像头的图像在背景层显示,识别到物体后,在前景层画矩形框,因为前景层使用了ARGB1555这种带透明度的格式,所以虽然有前景层,也能看到摄像头的图像,关于液晶屏的分层显示,可以先参考:【GD32450I-EVAL】+ 04液晶屏层叠显示与透明度调整测试
4 物体识别效果展示
演示视频:
|