前言

        前两篇文章介绍了扫线和图像预处理,而当图像的边界线出来之后,还需要通过边界线来找到一些特征。比如断行,拐点。这一章介绍一些元素处理的预备节根据拐点补线。


一、拐点

        拐点就是边界线开始不按照正常斜率的那一点,比如十字,圆环等处发生边界断行,这时候断行的那一点我们称为拐点。识别拐点的方法有很多,这里介绍我用过的几种方法。

1.通过边界线连续三点差值来判断。

        当连续3个点的差值大于设定阈值,就可以说明拐点存在。这个阈值取决于摄像头的角度和高度,不同的角度可能差的会比较大。这种方式在搜取拐点时效果挺好,不过因为一般情况下都是全图扫描,比较浪费。所以在第一种方法上我采用边线提取的同时,也进行拐点判断。

2.断行时搜索拐点。

         在采用跟踪搜线时,遇到一些元素时会明显有断行存在或者边界线不按照原本的斜率。这时候边界线就不存在或者我们没有搜到,这时候我们就可以判断上拐点和下拐点了。

        这里我是将按照边界的常规斜率搜线时没有搜到,比如正常我们不对图像进行逆透视变换时,边界线时一条斜线,赛道靠近车近处大,后面越来越小。这样当我们正常的提取边界时,当斜率发生变化了,就搜不到线。所以这时候我们向外搜线,如果存在边界,那么前一行我们就判断是下拐点。

        简单来说就是边界连续时,边界线从向内倾斜变成了向外倾斜的情况的那一点,就是下拐点。

       那么对于上拐点时,采用的方法也有相通的地方,当断行后,重新找到边界,这重新找到的一点就是上拐点。可以在搜寻拐点时,对拐点所在行进行限制,避免赛道外存在,或者拐点乱飞。

拐点存在的几种常见情况,A,B,C,a,b就是下拐点和上拐点。 

二、利用拐点补线

1.补线的应用

        对于正常弯道和直道,拐点一般不存在,但是在十字,三岔,圆环这里,就比较明显。尤其我们还需要利用拐点去进行补线,将空白的赛道拟合出我们需要的边界线。  这样我们经过这些元素时可以在我们需要的时候做出直行,打角等动作。

2.补线的方法

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;
}

补线结果实例