第19届智能车 十字处理思路附代码
十字得处理关键是在于拐点(角点)(突变点)的寻找,找拐点的思路有很多种,基本上我都了解过,这里我只介绍最简单最直观而且好调的方法。我第一次写文章,内容可能不够详细,如果有疑问可以在评论区留言,我会看到并及时更新补充。结合了博主的思路和我自己的思路,我在这里为大家梳理一下。有了拐点之后,识别十字就很方便了。圈出来的那个点就是标准的拐点。左上、右上、右下拐点的思路同理,这里不再赘述。本人的代码元素处理
·
本人的代码元素处理框架来自于这位博主的文章。
第18届全国大学生智能汽车竞赛四轮车开源讲解【5】--直道、弯道、十字_智能车竞赛开源-CSDN博客
结合了博主的思路和我自己的思路,我在这里为大家梳理一下。


十字得处理关键是在于拐点(角点)(突变点)的寻找,找拐点的思路有很多种,基本上我都了解过,这里我只介绍最简单最直观而且好调的方法。


圈出来的那个点就是标准的拐点。有以下几种特点:
1.上面几个点横坐标与拐点差距较大。
2.下面点横坐标于拐点差距不大。
3.上方出现丢线。
/*-------------------------------------------------------------------------------------------------------------------
@brief 左下角点检测
@param 起始点,终止点
@return 返回角点所在的行数,找不到返回0
Sample Find_Left_Down_Point(int start,int end);
@note 角点检测阈值可根据实际值更改
-------------------------------------------------------------------------------------------------------------------*/
uint8 Find_Left_Down_Point(int start,int end)//找四个角点,返回值是角点所在的行数
{
uint8 i,t;
uint8 left_down_line=0;
if(Left_Lost_Time>=0.9*MT9V03X_H)//大部分都丢线,没有拐点判断的意义
return left_down_line;
if(start<end)
{
t=start;
start=end;
end=t;
}
if(start>=MT9V03X_H-1-5)//下面5行数据不稳定,不能作为边界点来判断,舍弃
start=MT9V03X_H-1-5;
if(end<=MT9V03X_H-Search_Stop_Line)
end=MT9V03X_H-Search_Stop_Line;
if(end<=5)
end=5;
for(i=start;i>=end;i--)
{
if(left_down_line==0&&//只找第一个符合条件的点
abs(Left_Line[i]-Left_Line[i+1])<=3&&//角点的阈值可以更改
abs(Left_Line[i+1]-Left_Line[i+2])<=3&&
abs(Left_Line[i+2]-Left_Line[i+3])<=3&&
(Left_Line[i]-Left_Line[i-2])>=6&&
(Left_Line[i]-Left_Line[i-3])>=10&&
(Left_Line[i]-Left_Line[i-4])>=10)
{
left_down_line=i;//获取行数即可
break;
}
}
return left_down_line;
}
左上、右上、右下拐点的思路同理,这里不再赘述。
有了拐点之后,识别十字就很方便了。看下面这张图。

这是标准的正入十字,他的特点如下:
1.四个拐点都有。
2.左右都丢线。
这两个条件判断十字足够了
/*-------------------------------------------------------------------------------------------------------------------
@brief 十字检测
@param null
@return null
Sample Cross_Detect(void);
@note 利用四个拐点判别函数,查找四个角点,根据找到拐点的个数决定是否补线
-------------------------------------------------------------------------------------------------------------------*/
void Cross_Detect(void)
{
uint8 down_search_stop_l=0;//下点搜索开始行
uint8 down_search_stop_r=0;//下点搜索开始行
Cross_Flag=0;
if(Island_State==0&&Ramp_Flag==0)//与环岛互斥开
{
Left_Up_Find=0;
Right_Up_Find=0;
if(Both_Lost_Time>=10)//十字必定有双边丢线,在有双边丢线的情况下再开始找角点
{
//Scan_line_l2r();//右线重扫
//Find_Up_Point( MT9V03X_H-1, 0 );
Right_Up_Find=Find_Right_Up_Point(image_h-10,10);
Left_Up_Find=Find_Left_Up_Point(image_h-10,10);
//ips200_show_uint(60, 210, Right_Up_Find, 3);
//ips200_show_uint(10, 210, Left_Up_Find, 3);
if(Left_Up_Find==0&&Right_Up_Find==0)//只要没有同时找到两个上点,直接结束
{
return;
}
}
if(Left_Up_Find!=0&&Right_Up_Find!=0)//找到两个上点,就找到十字了
{
Cross_Flag=1;//对应标志位,便于各元素互斥掉
down_search_stop_l=Left_Up_Find;
down_search_stop_r=Right_Up_Find;
Right_Down_Find=Find_Right_Down_Point(Boundry_Start_Right-3,down_search_stop_l+2);
Left_Down_Find=Find_Left_Down_Point(Boundry_Start_Left-3,down_search_stop_r+2);
if(Left_Down_Find<=Left_Up_Find)
{
Left_Down_Find=0;//下点不可能比上点还靠上
}
if(Right_Down_Find<=Right_Up_Find)
{
Right_Down_Find=0;//下点不可能比上点还靠上
}
/********************************************下面是十字处理******************************************************************************/
if(Left_Down_Find!=0&&Right_Down_Find!=0)
{//四个点都在,无脑连线,这种情况显然很少
Left_Add_Line (Left_Line [Left_Up_Find ],Left_Up_Find ,Left_Line [Left_Down_Find ] ,Left_Down_Find);
Right_Add_Line(Right_Line[Right_Up_Find],Right_Up_Find,Right_Line[Right_Down_Find],Right_Down_Find);
}
else if(Left_Down_Find==0&&Right_Down_Find!=0)//11//这里使用的都是斜率补线
{//三个点 //01
//Lengthen_Left_Boundry(Left_Up_Find-1,MT9V03X_H-1);
extendline_l(limit_a_b_uint8(Left_Up_Find-7,Search_Stop,image_h-1),Left_Up_Find-2);
Right_Add_Line(Right_Line[Right_Up_Find],Right_Up_Find,Right_Line[Right_Down_Find],Right_Down_Find);
}
else if(Left_Down_Find!=0&&Right_Down_Find==0)//11
{//三个点 //10
Left_Add_Line (Left_Line [Left_Up_Find ],Left_Up_Find ,Left_Line [Left_Down_Find ] ,Left_Down_Find);
//Lengthen_Right_Boundry(Right_Up_Find-1,MT9V03X_H-1);
extendline_r(limit_a_b_uint8(Right_Up_Find-7,Search_Stop,image_h-1),Right_Up_Find-2);
}
else if(Left_Down_Find==0&&Right_Down_Find==0)//11
{//就俩上点 //00
//Lengthen_Left_Boundry (Left_Up_Find-1,MT9V03X_H-1);
//Lengthen_Right_Boundry(Right_Up_Find-1,MT9V03X_H-1);
extendline_l(limit_a_b_uint8(Left_Up_Find-7,Search_Stop,image_h-1),Left_Up_Find-2);
extendline_r(limit_a_b_uint8(Right_Up_Find-7,Search_Stop,image_h-1),Right_Up_Find-2);
}
}
else
{
Cross_Flag=0;
}
}
}
个人认为斜入十字没必要单独处理。
下一篇文章我会详细讲解如何补线。
我第一次写文章,内容可能不够详细,如果有疑问可以在评论区留言,我会看到并及时更新补充。
更多推荐



所有评论(0)