赞
踩
前两篇文章介绍了扫线和图像预处理,而当图像的边界线出来之后,还需要通过边界线来找到一些特征。比如断行,拐点。这一章介绍一些元素处理的预备节根据拐点补线。
拐点就是边界线开始不按照正常斜率的那一点,比如十字,圆环等处发生边界断行,这时候断行的那一点我们称为拐点。识别拐点的方法有很多,这里介绍我用过的几种方法。
1.通过边界线连续三点差值来判断。
当连续3个点的差值大于设定阈值,就可以说明拐点存在。这个阈值取决于摄像头的角度和高度,不同的角度可能差的会比较大。这种方式在搜取拐点时效果挺好,不过因为一般情况下都是全图扫描,比较浪费。所以在第一种方法上我采用边线提取的同时,也进行拐点判断。
2.断行时搜索拐点。
在采用跟踪搜线时,遇到一些元素时会明显有断行存在或者边界线不按照原本的斜率。这时候边界线就不存在或者我们没有搜到,这时候我们就可以判断上拐点和下拐点了。
这里我是将按照边界的常规斜率搜线时没有搜到,比如正常我们不对图像进行逆透视变换时,边界线时一条斜线,赛道靠近车近处大,后面越来越小。这样当我们正常的提取边界时,当斜率发生变化了,就搜不到线。所以这时候我们向外搜线,如果存在边界,那么前一行我们就判断是下拐点。
简单来说就是边界连续时,边界线从向内倾斜变成了向外倾斜的情况的那一点,就是下拐点。
那么对于上拐点时,采用的方法也有相通的地方,当断行后,重新找到边界,这重新找到的一点就是上拐点。可以在搜寻拐点时,对拐点所在行进行限制,避免赛道外存在,或者拐点乱飞。
拐点存在的几种常见情况,A,B,C,a,b就是下拐点和上拐点。
对于正常弯道和直道,拐点一般不存在,但是在十字,三岔,圆环这里,就比较明显。尤其我们还需要利用拐点去进行补线,将空白的赛道拟合出我们需要的边界线。 这样我们经过这些元素时可以在我们需要的时候做出直行,打角等动作。
1.通过两点拉线补线
拉线正常理解就是通过已知的两点,不断在这两点之间填中线点。
已知A,B两点,第一次我们填上A,B中心点C,第二次填入D点,直到A,B之间所有行都填满。下面附上代码
- /******************************************************************************
- *
- //曲线拟合 CommonRectificate(&P_LeftBlack[0],startPos-1,endPos+1);
- ******************************************************************************/
- void CommonRectificate(unsigned char data[],unsigned char begin,unsigned char end)
- {
- unsigned char MidPos = 0;
- if (end > 60-1)
- {
- end = 60-1;
- }
- if (begin == end)
- {
- data[begin] = (data[begin-1]+data[begin+1])>>1;
- // BlackLineData[begin] = LeftBlack[begin] + (RightBlack[begin]-LeftBlack[begin])/2;
- }
- else if(begin < end)
- {
- MidPos = (begin+end)>>1;
- data[MidPos] = (data[begin]+data[end])>>1;
- //BlackLineData[MidPos] = LeftBlack[MidPos] + (RightBlack[MidPos]-LeftBlack[MidPos])/2;
- if (begin+1 < MidPos)
- {
- CommonRectificate(data,begin,MidPos);
- }
- if (MidPos+1 < end)
- {
- CommonRectificate(data,MidPos,end);
- }
- }
- }
2.通过最小二乘法补线
在一些情况下,我们只能知道一点的位置,这时候我们可以通过已知的几个连续点来预测接下来的几点位置。由最小二乘法求得斜率,可以通过简单的运算得到接下来几点的坐标。
附上最小二乘法求斜率代码
- //最小二乘法拟合斜率
-
- float Slope_Calculate(uint8 begin,uint8 end,uint8 *p)
- {
- float xsum=0,ysum=0,xysum=0,x2sum=0;
- uint8 i=0;
- float result=0;
- static float resultlast;
- p=p+begin;
- for(i=begin;i<end;i++)
- {
- xsum+=i;
- ysum+=*p;
- xysum+=i*(*p);
- x2sum+=i*i;
- p=p+1;
- }
- if((end-begin)*x2sum-xsum*xsum) //判断除数是否为零
- {
- result=((end-begin)*xysum-xsum*ysum)/((end-begin)*x2sum-xsum*xsum);
- resultlast=result;
- }
- else
- {
- result=resultlast;
- }
- return result;
- }
补线结果实例
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。