接上篇,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通道适当压缩,把明暗不同的相同颜色识别为一种。

最终结果

线缆颜色顺序检测(续)

相关文章: