颜色识别功能是火星人视觉传感器的基本的功能,现有视觉传感器颜色识别距离有限,不适用于多颜色场景。针对这些问题,本传感器采用改进的数字图像处理算法,能完成多个物体颜色识别,提升准确率。处理过程分为三个步骤:图像预处理、颜色识别和识别结果滤波。基本原理是利用HSV域的特性,对图像进行处理。
具体的代码参考:https://github.com/BluesYu/MarStech_Vision_Sensor/tree/master/color_mode
HSV(色调、饱和度、亮度)参数与颜色对应的关系,本传感器做了轻微的调整。
参数 |
黑色 (BK) |
灰色 (GY) |
白色 (WT) |
红色(RD) |
橙色 (OG) |
黄色(YL) |
绿色(GN) |
青色(DKGN) |
蓝色(BU) |
紫色(PL) |
|
hmin |
0 |
0 |
0 |
0 |
156 |
11 |
26 |
35 |
78 |
90 |
125 |
hamx |
180 |
180 |
180 |
10 |
180 |
25 |
34 |
77 |
99 |
124 |
155 |
smin |
0 |
0 |
0 |
43 |
43 |
43 |
43 |
43 |
43 |
43 |
|
smax |
255 |
43 |
30 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
|
vmin |
0 |
46 |
221 |
46 |
46 |
46 |
46 |
46 |
46 |
46 |
|
Vmax |
46 |
220 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
图像预处理分为三个步骤:去噪、图像增强、转换颜色模型三个步骤。作为备选方案,去噪可以推荐使用(快速中值滤波算法+双边滤波算法)的组合滤波算法,示例代码没有使用。
图像增强推荐使用拉普拉斯图像增强,对图像进行锐化处理。
图像处理完成之后,从RGB域转换到HSV域,具体的方法如下所示:
颜色识别可分为两个步骤:图像颜色遍历和物体轮廓查找。首先根据HSV(色调、饱和度、亮度)模型中的色度数值,对颜色进行分类,对10种颜色进行分类,但是由于环境中背景一般采用黑、灰、白三种颜色,因此不检测该三种颜色,将此三种颜色点成为背景点,其他的为颜色点。同时橙色和青色容易被认为是黄色和蓝色,为了增加传感器使用的可靠性,避免造成误解,仅仅检测五种颜色:红色、黄色、绿色、蓝色和紫色。
使用测试视频,测试结果如下:
通过上图可以看到,因此需要采用结果滤波算法来去除大量的噪点,因此需要使用结果滤波算法,结果滤波算法如下所示,其中AB代表传感器高度,视觉传感器位置在A点,视觉传感器摄像头识别角度为60度,默认垂直地面放置,而A点与球体切线的与球体相交的点为C、D,假设 AB=10cm(即传感器离地面有10cm),BC=200cm,根据几何原理得到角DAB为90度,则计算角度α 。通过比例换算,可知传感器图像中球体在42*42像素的大小范围内。因此设计滤波算法,通过轮廓检测后,将矩形轮廓尺度小于42*42像素的物体直接滤除。
用于颜色识别的代码(https://github.com/BluesYu/MarStech_Vision_Sensor/tree/master/color_mode)中,使用要求如下:
1,需要使用摄像头;
2,采集图像信息,通过串口发送;
3,依赖简易的opencv库函数,可以使用白平衡算法;
4, 测试函数编译命令为:g++ color_mode_test.cpp color_mode.cpp uart_io.cpp -o color_mode_test -lopencv_core -lopencv_highgui -lopencv_imgproc -lpthread -std=c++11
代码主体为color_mode.h和color_mode.cpp,测试代码为color_mode_test.cpp,用来测试颜色识别功能,代码中有详细的注释。
/******************************************************************************************************
* 函数(Function):find_color(Mat &src, vector &color_name,vector &rect_dst, string color)
* 功能(Description): 查找目标图片的轮廓,标记颜色
* 调用函数(Calls):findContours()等
* 输入参数(parameter):Mat &src:输入图像
vector &color_name:保存轮廓的颜色数组
vector &rect_dst:保存轮廓矩形数组
string color:颜色标记
* 返回数值(return): -1:检测失败,即没有轮廓
正数:轮廓的个数
* 其他(Others):可以添加形态学处理算法
********************************************************************************************************/
int find_color(Mat &src, vector &color_name, vector &rect_dst, string color);
/******************************************************************************************************
* 函数(Function):expand_color_image(Mat &srcImg, Mat &dstImg)
* 功能(Description): 对图像进行形态学处理
* 调用函数(Calls):erode(),dilate()等
* 输入参数(parameter):Mat &srcImg:输入图像
Mat &dstImg:输出图像
* 返回数值(return): 无
* 其他(Others):可以修改形态学处理算法模板大小
********************************************************************************************************/
void expand_color_image(Mat &srcImg, Mat &dstImg);
/******************************************************************************************************
* 函数(Function)get_color_pic(Mat &src, Mat &RD, Mat &YL, Mat &GN, Mat &BU, Mat &PL)
* 功能(Description):获取五种颜色的模板
* 调用函数(Calls):cvtColor(),get_color_num()等
* 输入参数(parameter):Mat &src:输入图像 Mat &RD:红色
* Mat &YL:黄色 Mat &GN:绿色
* Mat &BU:蓝色 Mat &PL:紫色
* 返回数值(return): return =-1:检测失败,参数范围溢出
* return = 0:检测成功
* 其他(Others):图像的参数:S(饱和度)和V(明度),范围可以调节,主要用于调节背景颜色(黑、白、灰)
********************************************************************************************************/
int get_color_pic(Mat &src, Mat &RD, Mat &YL, Mat &GN, Mat &BU, Mat &PL);
/******************************************************************************************************
* 函数(Function): get_color_num(int &num)
* 功能(Description):根据H(色调)数值,判断对应的颜色区间
* 调用函数(Calls):无
* 输入参数(parameter):int &num:输入H(色调)数值。
* 返回数值(return): return =-1:检测失败,五种颜色
* return = 1:红色
* return = 2:黄色
* return = 3:绿色
* return = 4:蓝色
* return = 5:紫色
* 其他(Others):默认的阈值是:h_min[6] = { 0,156,30,35,105,125 };
h_max[6] = { 8,180,34,77,124,155 };
阈值范围可以调节。
********************************************************************************************************/
int get_color_num(int &num);
/******************************************************************************************************
* 函数(Function):get_color_mode(Mat &framem, vector color_name, vector Rect_center, vector Rect_size)
* 功能(Description):获取五种颜色的模板
* 调用函数(Calls):get_pic(),find_color()等
* 输入参数(parameter):Mat &frame:输入图像
* vector &color_name:检测颜色数组
* vector &Rect_center:对应中心坐标
* vector &Rect_size:矩形尺寸(长和宽)
* 返回数值(return): return =-1:图像获取失败
* return =-2:未监测到轮廓
* return = 正数:检测得到参数
* 其他(Others):
********************************************************************************************************/
int get_color_mode(Mat &frame, vector &color_name, vector &Rect_center, vector &Rect_size);
参考代码示例在color_mode_test.cpp中,直接调用库函数即可。
vector color_name;
vector Rect_center;
vector Rect_size;
if (get_color_mode(frame, color_name, Rect_center, Rect_size) > 0)
{
...
}
使用打印函数,打印出具体的位置(颜色名称、中心点坐标、矩形区域长宽)即可,代码如下:
strcpy(color_temp,color_name[i].c_str());
color_temp[2]=' ';
len=UART_Send(fd,(unsigned char*)color_temp,3);//颜色
unsigned char temp[5];
int2char_num(Rect_center[i].x,temp);
len=UART_Send(fd,(unsigned char*)temp,4);//x
int2char_num(Rect_center[i].y,temp);
len=UART_Send(fd,(unsigned char*)temp,4);//y
int2char_num(Rect_size[i].x,temp);
len=UART_Send(fd,(unsigned char*)temp,4);//w
int2char_num(Rect_size[i].y,temp);
temp[4]='\n';
len=UART_Send(fd,(unsigned char*)temp,5);//h
备注:颜色识别时火星人视觉传感器中的一项功能,完整项目介绍:https://blog.csdn.net/Bluesyxx/article/details/98474347
具体视觉传感器测试、购买可以咨询:火星人俱乐部官网(https://www.imarsclub.com/web/index),电话或邮件联系即可。传感器已经申请专利,商业使用需要授权。
火星人视觉传感器是一个开放平台,相关电路版图、代码对外开放,可以自行下载,代码地址:https://github.com/BluesYu/MarStech_Vision_Sensor,欢迎star和fork,有问题可以再github上交流。
本项目为开源项目,不以盈利为目的,开源社区需要大家一起努力,欢迎大家一起来开发!