接上篇,https://blog.csdn.net/iamqianrenzhan/article/details/83537779
原来的算法使用HSV颜色空间,对一些颜色不能区分,而且经过后续测试,对光照的变化的鲁棒性也没有CIELAB颜色空间好。
算法流程
预处理
预处理流程和上一篇类似,只是转换为LAB颜色空间
cvtColor(src_all, hsv, CV_BGR2Lab);
边界识别
和上一篇类似,得到图片长度方向上得到其hsv颜色空间的平均值
float L[WIDTH] = { 0 };
float A[WIDTH] = { 0 };
float B[WIDTH] = { 0 };
float LL[WIDTH] = { 0 };
float AA[WIDTH] = { 0 };
float BB[WIDTH] = { 0 };
int pointcount[WIDTH] = { 0 };
for (int i = 0; i < hsv.size().width; i++)
{
float h, s, v;
h = 0;
s = 0;
v = 0;
for (int j = hsv.size().height / 2; j < hsv.size().height / 2 + 2; j++) //hsv.size().height
{
Vec3b vec3b = hsv.at<Vec3b>(j, i);
h += vec3b[0];
s += vec3b[1];
v += vec3b[2];
}
L[i] = h;
A[i] = s;
B[i] = v;
}
绘制的折线图
然后进行分割
//需要对数据进行平滑
int filtersize = 5;
for (int i = filtersize; i < WIDTH- filtersize; i++)
{
int suml = 0, suma = 0, sumb = 0;
for (int j = -filtersize; j <= filtersize; j++)
{
suml += L[i + j];
suma += L[i + j];
sumb += L[i + j];
}
LL[i] = suml / (filtersize * 2 + 1);
AA[i] = suma / (filtersize * 2 + 1);
BB[i] = sumb / (filtersize * 2 + 1);
}
//用球包含空间附近的点
for (int i = 0; i < WIDTH; i++)
{
int j = -20;
int jmax = 20;
for (; j <= jmax; j++)
{
if (i + j >= 0 && i + j < WIDTH)
{
int dis = (LL[i] - LL[i + j])*(LL[i] - LL[i + j])
+ (AA[i] - AA[i + j])*(AA[i] - AA[i + j])
+ (BB[i] - BB[i + j])*(BB[i] - BB[i + j]);
if (dis < 1000)
pointcount[i]++;
}
}
}
//pointcount找极小值
int position[30] = { 0 };
int position_left[30] = { 0 };
int position_right[30] = { 0 };
int current_position_count = 0;
bool done_flag = 0;
for (int i = 1; i <= 35; i++)
{
for (int j = 100; j < WIDTH-100; j++)
{
if (pointcount[j] == i)
{
done_flag = 0;
for (int k = 0; k < current_position_count; k++)
{
if (j > position_left[k] - 30 && j < position_right[k] + 30)
{
//加入当前position
if (j < position_left[k])
position_left[k] = j;
if (j > position_right[k])
position_right[k] = j;
done_flag = 1;
}
}
//如果和所有的都不符合,建立新的的position
if (!done_flag)
{
position_left[current_position_count] = j;
position_right[current_position_count] = j;
position[current_position_count] = j;
current_position_count++;
}
}
}
}
处理后结果
黑色线是处理后指标,蓝色点是指标的极小值。
效果比使用HSV颜色空间好很多,而且由于使用的新的算法,考虑了线缆的空间约束,识别的稳定性大幅提高。
颜色识别
颜色识别仍使用欧式距离的方式,但是考虑到光照的不均匀和变化,可以把L通道适当压缩,把明暗不同的相同颜色识别为一种。