在我们得到一张稳定的二值化图像后,就可以对图像进行一些寻线的处理,在这里简单提一下,那就是图像第一行所在的位置,作为初学者的我刚开始就曾搞错,摄像头第一行所在的位置取决于你摄像头是正装还是反装,如果是正装那么对应远离车身所对应的是第一行,靠近的为最大行。反装则相反,但是还需注意的是正装和反装所对应的左右行数也是不同的,在存放左右边界时需要注意,两者是相反的。关于摄像头是如何放置的问题,其实两者并没有太大的区别,如何放置根据个人的考虑决定了。
个人认为摄像头的巡线可以分为3类:
一类是最基础,也是最简单的,由中线分别往左右两边扫,寻找黑白的跳变点,存放到左右边界数组中。
二是对固定对靠近车身的一行或是5行进行扫描,确定左右边界后,根据上一个左右边界所在列数的周围进行之后行数的扫描,这也是我比赛所用到的寻线方式。
三就是所谓的种子生长法,其初始方向和第二种方式一样,对最靠近车身的一行进行扫描,得到左右边界,以寻到的两个点为基础,框出一个3*3的矩形框,分别对左右两个点所在的矩阵框内进行顺时针和逆时针扫描,找到跳变点,依次往下扫描,这样就可以寻出一条完整的边线,只不过当时时间比较短,所以没有继续往下深究。
首先我们需要定义几个数组来存放我们之后得到的一些数据
int leftline[120]; //赛道左边界
int rightline[120]; //赛道右边界
int centerline[120]; //赛道中间线
int road_width[120];//道路宽度 这里的80是我只扫描了80行
下面先给出第一种的寻线,可以让小车早点的跑起来:
int line=0;
int list=0;
void image_scan()
{
for(line=120;line>=40;line--)
{
for(list=93;list<188;list++)
{
if((image_deal[line][list-2]==white)&&(image_deal[line][list-1]==black)
&&(image_deal[line][list]==black))
{
rightline[line]=list;
break;
}
}
for(list=93;list>1;list--)
{
if((image_deal[line][list]==black)&&(image_deal[line][list+1]==black)
&&(image_deal[line][list+2]==white))
{
leftline[line]=list;
break;
}
}
road_width[line]=my_abs(leftline[line],rightline[line]);
centerline[line]=(rightline[line]+leftline[line])/2;
}
}
第二种寻线法:
uint8 first_scan()
{
int line=(MT9V03X_CSI_H-1);
int list=0;
uint8 start_list = 0;
uint8 Find_Left=0; //寻到左线标志位
uint8 Find_Right=0; //寻到右线标志位
if (image_deal[line][center] == white) //开始扫描第一行的左右边界
{
for (list = center; list >= 3; list--)
{
if ((image_deal[line][list - 1] == black) && (image_deal[line][list] == black)
&&(image_deal[line][list + 1] == white)) //黑白白
{
leftline[line] = list + 1; //左边界数组
Find_Left = 1; //找到了左线
break;
}
}
if (Find_Left == 0) //没找到 以最左边为边界
{
leftline[line] = 1;
}
//-----------左边界完成-------------
for (list = center; list <= cutCOL - 2; list++)
{
if ((image_deal[line][list - 1] == white) && (image_deal[line][list] == black)
&& (image_deal[line][list + 1] == black)) //白嘿嘿。。黑尼玛
{
rightline[line] = list - 1;
Find_Right = 1;
break;
}
}
if (Find_Right == 0) // 没找到右边界
{
rightline[line] = (cutCOL - 1); //以扫描图像的最右边一列-1为边界
} //-------------右边界完成----------
}
road_width[line] = my_abs(leftline[line], rightline[line]);
centerline[line] = (rightline[line] + leftline[line]) / 2;
last_left_line = leftline[line];
last_right_line = rightline[line];
return start_list;
}
void Follow_scan()
{
for (line = MT9V03X_CSI_H - 1 - 1; line >= 40; line--)
{
Find_left = 0;
Find_right = 0;
if ((last_left_line - follow_can - flag_cross) < 0)
scan_start_left = 0;
else
scan_start_left = (last_left_line - follow_can - flag_cross);
if ((last_left_line + follow_can * 3 + flag_cross) >= (cutCOL - 2))
scan_end_left = (cutCOL - 3);
else
scan_end_left = (last_left_line + follow_can * 3 + flag_cross);
for (list = scan_start_left; list <= scan_end_left; list++)
{
if ((image_deal[line][list] == black) && (image_deal[line][list + 1] == white)
&&(image_deal[line][list + 2] == white))
{
leftline[line] = list;
Find_left = 1;
break;
}
}
if (Find_left == 0)
{
// leftline[line]=0;
left_lost_flag[line] = 1;
left_lost_count++;
if (flag_of_leftbreak == 0)
{
l_start++;
}
}
else
{
flag_of_leftbreak = 1; //break标志成立
}
//---------------------------------------------------------左线完毕------------------
if ((last_right_line + follow_can + flag_cross) >= (cutCOL))
scan_start_right = (cutCOL - 2);
else
scan_start_right = (last_right_line + follow_can + flag_cross);
if ((last_right_line - follow_can * 3 + flag_cross) <= 2)
scan_end_right = 2;
else
scan_end_right = (last_right_line - follow_can * 3 + flag_cross);
for (list = scan_start_right; list >= scan_end_right; list--) //-------右边界开始寻线-
{
if ((image_deal[line][list - 2] == white) && (image_deal[line][list - 1] == white)
&&(image_deal[line][list] == black))
{
rightline[line] = list;
Find_right = 1;
break;
}
}
if (Find_right == 0)
{
// rightline[line]=(cutCOL-1);
right_lost_flag[line] = 1;
right_lost_count++;
if (flag_of_rightbreak == 0) //如果在这一行之前没有遭遇断线,则计数
{
r_start++;
}
}
else //扫到线
{
//lostright_times不继续增加
flag_of_rightbreak = 1; //break标志成立
}
//-------------------------------------------------------右边界结束-------------------
road_width[line] = (rightline[line] - leftline[line]); 初步计算赛道宽度
centerline[line] = (leftline[line] + rightline[line]) / 2;
}
}
第三种巡线方式之后如果能够写出来,可能会添上。
至此对于图像的基本寻线就结束了,下一章就是对一些元素进行特征提取
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)