图像处理------>基础扫线
基础扫线
中间扫线
在我的整个代码中,大体使用的就是中间扫线的方法,但针对于每种特殊元素,其实是使用了中间扫线一些小变种,大体就是更改一些扫线的条件啦,更改扫线的起始点之类的,但从最基础的来讲,就是中间扫线。所以我平时也称中间扫线为基础扫线(其实后来是写过八领域扫线的,只不过当时已经在暑假最后的集训了,我担心更换扫线方式会导致我的代码要修改一些细节,所以就没有再换,但是我跑过近三个月的图,都没有出bug,应该还算稳定)
防扫丢函数
对于中间扫线来说,其实当你前进到下一行并且你的扫描点不在赛道内的时候就算扫完了,但是我在这个的基础上增加了一个函数来防止一些特殊情况下图像扫丢。
byte Find_Lose(byte rec_start, byte i)//起始行,起始列
{
byte kk = 1;
while (rec_start + kk < 185 && rec_start - kk > 0 && i < 61)
{
if (BinPixels[i][rec_start + kk] != 0 && BinPixels[i + 2][rec_start + kk] != 0 && BinPixels[i + 4][rec_start + kk] != 0 && BinPixels[i + 6][rec_start + kk] != 0)
{
return (byte)(rec_start + kk);
}
if (BinPixels[i][rec_start - kk] != 0 && BinPixels[i + 2][rec_start - kk] != 0 && BinPixels[i + 4][rec_start - kk] != 0 && BinPixels[i + 6][rec_start - kk] != 0)
{
return (byte)(rec_start - kk);
}
kk++;
}
Lose_line = i;//判断为丢线,并记录,将丢线行之上的左线与右线记录为最高的有效行的值
for (byte k = i; k < 70; k++)
{
if (k == 0) continue;
L_black[k] = L_black[k - 1];
R_black[k] = R_black[k - 1];
LCenter[k] = 0;
}
return 0xff;//扫丢返回255
}//扫线丢线后验证寻线
这个函数的思路其实很好理解,就是从扫丢的那个点开始,同时向左向右找,是否还存在一个点,它及它向上的一段都是白。如果存在,那我就认为这是一个合理的点,我的扫线就会从这里重新开始。 这个最关键的点在于同时向左向右扫线,并且在扫到图像边缘的时候结束,这样的话在弯道的时候就直接扫到赛道边缘结束掉,而不会出现误判的情况。
扫线部分
void image_line(byte rec_line, byte rec_start)
{
for (byte i = rec_line; i < 69; i++)
{
L_black[i] = 185;
R_black[i] = 0;
if (BinPixels[i][rec_start] == 0 && BinPixels[i + 1][rec_start] == 0)
{
rec_start = Find_Lose(rec_start, i);
if (rec_start == 255) return;
}
for (byte j = rec_start; j < 184; j++)
{
if (BinPixels[i][j] == 0 && BinPixels[i][j + 1] == 0)
{
L_black[i] = j;
break;
}
}
for (byte j = rec_start; j > 1; j--)
{
if (BinPixels[i][j] == 0 && BinPixels[i][j - 1] == 0)
{
R_black[i] = j;
break;
}
}
LCenter[i] = (byte)(L_black[i] / 2 + R_black[i] / 2);
if (BinPixels[i + 1][rec_start] == 0) rec_start = LCenter[i];
}
}
扫线的话其实就是中间扫线的思路,我是用扫到两个连续的黑像素作为边线条件的,这其实也比较常见。
