高级会员
- 积分
- 979
- 威望
- 522
- 贡献
- 271
- 兑换币
- 333
- 注册时间
- 2015-11-1
- 在线时间
- 93 小时
- 毕业学校
- UPC
|
4#
楼主 |
发表于 2016-2-1 18:02:14
|
只看该作者
自己看吧,不想单独写了,直接从我程序中提取的
void search_line(void)
{
int8 Row_Ptr=0;//行计数参量
int8 Col_Ptr=0;//列计数参量
int8 Left_End=0;//寻左线列截止数
int8 Right_End=0;//寻右线列截止数
track.Left_Valid_Count=0;//默认左边沿有效连续计数值为0
track.Right_Valid_Count=0;//默认右边沿有效连续计数值为0
track.Left_Invalid_Count=0;//默认左边沿无效连续计数值为0
track.Right_Invalid_Count=0;//默认右边沿无效连续计数值为0
Cross_Flag=0;//默认无十字
/*
*由于最近三行图像非常靠谱,利用从中间向两边分别寻找能找到靠谱的黑线
*/
for(Row_Ptr=ROW-1;Row_Ptr>ROW-3;Row_Ptr--)
{
track.Left_Line[Row_Ptr]=1;//初始化左黑线为1
track.Right_Line[Row_Ptr]=COLUMN-2;//初始化右黑线为COLUMN-2
track.Left_Valid[Row_Ptr]=0;//默认左边未找到黑线
track.Right_Valid[Row_Ptr]=0;//默认右边未找到黑线
track.Center_Line[Row_Ptr]=COLUMN/2;//默认中线为图像中间
//从中间开始往左寻线
for(Col_Ptr=COLUMN/2;Col_Ptr>0;Col_Ptr--)
{
if(img[Row_Ptr][Col_Ptr]==0 && img[Row_Ptr][Col_Ptr-1]==1)
{
track.Left_Line[Row_Ptr]=Col_Ptr-1;//黑线位置
track.Left_Valid[Row_Ptr]=1;//此行左黑线有效位置1
track.Left_Valid_Count++;//连续有效行+1
track.Left_Invalid_Count=0;
break;
}
}
if(track.Left_Valid==0)
{
track.Left_Valid_Count=0;
track.Left_Invalid_Count++;
}
//从中间开始往右寻线
for(Col_Ptr=COLUMN/2;Col_Ptr<COLUMN;Col_Ptr++)
{
if(img[Row_Ptr][Col_Ptr]==0 && img[Row_Ptr][Col_Ptr+1]==1)
{
track.Right_Line[Row_Ptr]=Col_Ptr+1;
track.Right_Valid[Row_Ptr]=1;
track.Right_Valid_Count++;
track.Right_Invalid_Count=0;
break;
}
}
if(track.Right_Valid==0)
{
track.Right_Valid_Count=0;
track.Right_Invalid_Count++;
}
}
/*
*由于梯形失真导致左边的黑线是从下往上向右收敛,右边的黑线是从下往上向左收敛(除非
*弯道,左黑线向左收敛可能是S弯道或者左拐弯还有十字,右黑线向右收敛可能是S弯或者右
*拐弯还有十字),利用这也特点,当出现相反情况时判断是否是突变点,可以识别斜入十字
*,而直入十字判断则用连续白行即可
*/
if(track.Left_Valid_Count==3&&track.Right_Valid_Count==3)//最近三行左右均找到黑线
{
for(Row_Ptr=ROW-4;Row_Ptr>Drop_Row;Row_Ptr--)
{
track.Left_Line[Row_Ptr]=1;//初始化为1
track.Left_Valid[Row_Ptr]=0;//初始化每行无效
Col_Ptr=track.Left_Line[Row_Ptr+1]+6;//具体数值还需视情况而定
Left_End=track.Left_Line[Row_Ptr+1]-6;
for(;Col_Ptr>Left_End;Col_Ptr--)
{
if(img[Row_Ptr][Col_Ptr]==0 && img[Row_Ptr][Col_Ptr-1]==1)
{
track.Left_Line[Row_Ptr]=Col_Ptr-1;//黑线位置
track.Left_Invalid_Count=0;//左线连续无效值清零
if(track.Left_Line[Row_Ptr]<track.Left_Line[Row_Ptr+1])//出现左线异常不向右收敛
{
Left_Turn_Count++;//左线收敛方向异常连续计数+1
track.Left_Valid[Row_Ptr]=1;//暂时标记此行左黑线有效位置1
break;
}
else//左线正常向右收敛
{
Left_Turn_Count=0;//左线收敛方向异常连续计数值清零
track.Left_Valid[Row_Ptr]=1;//此行左黑线有效位置1
break;
}
}
}
if(track.Left_Valid==0)//此行没有找到左黑线
track.Left_Invalid_Count++;
if(Left_Turn_Count==3)//左黑线收敛方向异常进一步判断是否为斜入十字
{
if(zxec_slope_calculate(Row_Ptr,Row_Ptr+3,track.Left_Line)*
zxec_slope_calculate(Row_Ptr+3,Row_Ptr+6,track.Left_Line)<-2)//要改
{
//通过此条件进一步确定为斜入十字
Cross_Flag=2;
//Left_Turn_Count=0;
Left_Turn_Row=Row_Ptr+3;
track.Left_Valid[Row_Ptr]=0;
track.Left_Valid[Row_Ptr+1]=0;
track.Left_Valid[Row_Ptr+2]=0;
//接下来应该利用竖直的线向上搜,找到十字结束行,这里用Left_Turn_End表示
for(;Row_Ptr>Drop_Row;Row_Ptr--)
{
track.Left_Valid[Row_Ptr]=0;
if(img[Row_Ptr][track.Left_Line[Left_Turn_Row]]==0 && img[Row_Ptr-1][track.Left_Line[Left_Turn_Row]]==1)
{
Left_Turn_End=Row_Ptr;
for(Col_Ptr=track.Left_Line[Left_Turn_Row];Col_Ptr<COLUMN;Col_Ptr++)
{
if(img[Row_Ptr][Col_Ptr]==1 && img[Row_Ptr][Col_Ptr+1]==0)
{
track.Left_Line[Left_Turn_End]=Col_Ptr;
track.Left_Valid[Row_Ptr]=1;
}
break;
}
for(Row_Ptr=Left_Turn_Row;Left_Turn_Row<Left_Turn_End;Row_Ptr--)//斜入十字补线
{
track.Left_Line[Row_Ptr]=track.Left_Line[Left_Turn_Row]+
(track.Left_Line[Left_Turn_End]-track.Left_Line[Left_Turn_Row])/ (Left_Turn_End-Left_Turn_Row)*(Row_Ptr-Left_Turn_Row);
track.Left_Valid[Row_Ptr]=1;
}
break;
}
}
if(Left_Turn_End==0)//向上搜线未找到结束行
{
for(Row_Ptr=Left_Turn_Row;Left_Turn_Row<Drop_Row;Row_Ptr--)//斜入十字补线
{
track.Left_Line[Row_Ptr]=track.Left_Line[Left_Turn_Row]+
(track.Left_Line[Left_Turn_Row]-track.Left_Line[Left_Turn_Row+3])/ (Left_Turn_Row-(Left_Turn_Row+3))*(Row_Ptr-Left_Turn_Row);
track.Left_Valid[Row_Ptr]=1;
}
}
}
}
if(track.Left_Invalid_Count==3)
{
track.Left_Break=Row_Ptr+3;//左边黑线断点行记录
break;//跳出大循环,停止搜线
}
}
}
}
|
|