智能车寻线算法之北科寻线可能用的方法
先上一张北科的寻线图片,从上图可以看出,北科的寻线方法能够寻找到方向向下的曲线,肯定和我们一般的左右寻线的方法有所不一样,我想了很久,查阅的了数字图像处理第三版,在我的资源里有
这种方法可以寻得和北科同样的效果,下面我对这种方法做详细的介绍,希望大家可以讨论一下一起提高。
手绘一张图,有点丑,还可以接受吧。
0代表黑色,1代表白色。
我们的赛道本来就是一个连通的区域,所以左边线和右边线肯定是一条连续的直线,这里我们先去除那些特殊的元素。如图所示,首先找到左第一个跳变点b,然后从b的右方开始围着b以逆时针的方向寻找黑白跳变,与b相邻一共有8个方向这个我不用画图大家都应该知道的。每次找打跳变跟新b的位置再以新a继续逆时针寻线,就能把一条完整的边线寻找出来,话不多说,大家看我的寻线图。
从图中可以明显的看出我也是能够寻出拐点之后的曲线了吧,哈哈。
刚开始做智能车图像处理,总是被以前的的左右寻线的行数思想限制住,现在这种寻线的方法不是以行为单位找线,而是跟踪曲线的生长寻线,就可以得到较好的曲线。这是出现了一个问题,左线和右线不相等,对于后面找中线的想法,也不能和以前一样是简单的左右取平均值了。
我再上一段代码供大家参考:
这是我寻左线的程序,右线同理,大家可以自己尝试。
有问题,可以评论一起进步。
int GetLeftRoadEdge(byte[,] Image, int Height, int Width, int[] LeftLine_Y, int[] LeftLine_X)
{
int Index_LeftCount = 0;
int Index_Y = 0;
int Index_X = 0;
for (int Y = Height - 1; Y > 80; Y--)
{
for (int X = Width / 2; X > 0; X--)
{
if (Image[Y, X + 1] == Withe && Image[Y, X] == Black)
{
LeftLine_X[0] = X + 1;
break;
}
}
if (LeftLine_X[0] >= 1)
{
LeftLine_Y[Index_LeftCount] = Y;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
break;
}
}
if (Index_LeftCount == 0)
return 0;
while (true)
{
if (Image[Index_Y, Index_X + 1] != Withe) //1
{
if (Image[Index_Y + 1, Index_X + 1] == Withe) //8
{
LeftLine_Y[Index_LeftCount] = Index_Y;
LeftLine_X[Index_LeftCount] = Index_X + 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y + 1, Index_X] == Withe) //7
{
LeftLine_Y[Index_LeftCount] = Index_Y + 1;
LeftLine_X[Index_LeftCount] = Index_X + 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y + 1, Index_X - 1] == Withe) //6
{
LeftLine_Y[Index_LeftCount] = Index_Y + 1;
LeftLine_X[Index_LeftCount] = Index_X;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y, Index_X - 1] == Withe) //5
{
LeftLine_Y[Index_LeftCount] = Index_Y + 1;
LeftLine_X[Index_LeftCount] = Index_X - 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y - 1, Index_X - 1] == Withe) //4
{
LeftLine_Y[Index_LeftCount] = Index_Y;
LeftLine_X[Index_LeftCount] = Index_X - 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y - 1, Index_X] == Withe) //3
{
LeftLine_Y[Index_LeftCount] = Index_Y - 1;
LeftLine_X[Index_LeftCount] = Index_X - 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y - 1, Index_X] == Withe) //2
{
LeftLine_Y[Index_LeftCount] = Index_Y - 1;
LeftLine_X[Index_LeftCount] = Index_X;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
}
else if (Image[Index_Y, Index_X + 1] != Withe) //2
{
LeftLine_Y[Index_LeftCount] = Index_Y;
LeftLine_X[Index_LeftCount] = Index_X + 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y - 1, Index_X] != Withe) //3
{
LeftLine_Y[Index_LeftCount] = Index_Y - 1;
LeftLine_X[Index_LeftCount] = Index_X;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y - 1, Index_X - 1] != Withe) //4
{
LeftLine_Y[Index_LeftCount] = Index_Y - 1;
LeftLine_X[Index_LeftCount] = Index_X - 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y, Index_X - 1] != Withe) //5
{
LeftLine_Y[Index_LeftCount] = Index_Y;
LeftLine_X[Index_LeftCount] = Index_X - 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y + 1, Index_X - 1] != Withe) //6
{
LeftLine_Y[Index_LeftCount] = Index_Y + 1;
LeftLine_X[Index_LeftCount] = Index_X - 1;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y + 1, Index_X] != Withe) //7
{
LeftLine_Y[Index_LeftCount] = Index_Y + 1;
LeftLine_X[Index_LeftCount] = Index_X;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
else if (Image[Index_Y + 1, Index_X + 1] != Withe) //8
{
LeftLine_Y[Index_LeftCount] = Index_Y + 1;
LeftLine_X[Index_LeftCount] = Index_X;
Index_Y = LeftLine_Y[Index_LeftCount];
Index_X = LeftLine_X[Index_LeftCount++];
}
if (Index_Y <= 1)
{
break;
}
if (Index_X == 0 || Index_X >= Width - 4)
{
break;
}
}
return Index_LeftCount;
}