算法总结——hough直线检测

    hough直线检测,是我用的图像检测方法中的另一个重点。hough的原理说起来比较简单,就是对原图中每个点可能经过的直线都进行累积,这些累积是在一个“可能经过的直线模版”即“RT模版”上进行的,最后根据累积值找出最可能的几条直线即可。

 

    我首先还是先阐述一下自己对matlab中直线检测步骤的理解。matlab中实现hough直线检测用到了3个函数,也是3个.m文件,分别是hough、houghpeaks和houghlines,三者也是按照这个顺序出场的。hough函数的作用就在于在一个离散的“RT空间”上完成累积,离散是一种无奈,因为我们的计算有限制,也是一种“相应的便利”,因为我们的原图像素也是离散的,RT空间的离散导致四舍五入,才可能对离散的原图像素点累积出可能的直线;接着是houghpeaks,它主要是用来找出“RT模版”上累积出来的几个最大的累积值,从而确定最可能是直线的直线,matlab在这个函数中加入了累似图像“非极大抑制”的处理,如果一个很小的RT区域中出现几个很大的累积点,那么会留下最大的一个舍弃其他的,这样的作用反应到原图上,我觉得应该是对较粗的直线起到防止反复检测出几条平行或者相交的直线来;最后是houghlines,这个函数得到真实的直线,它一方面考虑到“直线最小间隙”,另一方面考虑到“直线最小长度”。

 

    观察matlab中hough的实现,我根据自己的应用需求作了一些小的修改。首先是在matlab的hough函数上,我觉得仅仅离散的“RT空间”还是不太够的,我们把“RT空间”离散的越细,检测的直线就越精确,也可以说在原图中“需要检测的区域就越狭窄”,这一点matlab的hough函数可以办到,但是过细的“RT空间”,可能造成检测到的直线不连续,本来连续的边缘直线,由于存在角度T上的微小波动,可能会被认为是不用的直线来检测,当然,houghpeaks中的“类非极大抑制”可以防止对这样的一条真实边缘直线检测多次,但归根结底,不利于最后houghlines函数连出真实的直线来。基于此,我对“RT空间”采用“双精度”的处理方法,首先就像matlab的hough函数的做法那样,可以有一个增大“RT空间”精度的参数div来保证“检测的潜在直线的多样性”,然后对这个很细的“RT空间”通过一个参数com进行整合,一些“临近的多样性直线”被考虑成一条直线(即粗化的“RT空间”上的一个RT点),这样一个“双精度”的策略有利于连接出“真实的存在一点点波动的直线”。这里的通过参数com粗化“RT空间”和houghpeaks函数中的“类非极大抑制”作用的目的不同,这里的粗化是为了在一个粗一点点的“RT邻域”上保留所有的原图像素点,有利于实现直线连接,而“类非极大抑制”的作用是为了在一个粗很多多的“RT邻域”上舍弃邻域上的周围原图像素点,它有利于防止干扰和粗线的重复检测。

 

    另外一个小的修改是针对matlab的houghlines函数,houghlines函数是利用houghpeaks函数送来的可变个数的RT点,然后结合“间隙”和“长度”要求连接出所有符合条件的直线,而我是要针对指针类型的指针边缘直线检测,因此,我通过houghpeaks函数送来的RT点只有两个,通过com和houghpeaks对“非极大抑制区域”大小的控制,我可以保证这两个RT点对应指针的两个边缘。在得到这2个RT点后,下面我有2条路可选:一是直接根据RT信息就可以确定原图中的2个直线,它们有交点之类的信息,这样很自然就能得到它们的角平分线的角度和方向,指针检测的任务就完成了;二是像matlab的houghlines函数那样,连接出真实线段,但是我只保留houghlines函数中对“间隙”的考虑,不用考虑“最小长度”了,因为我在2个RT点上要各检测出最长的一条真实线段来,再利用2个最长线段的端点对表盘中心的位置来确定指针指向,第二种方法我走了弯路,当时没有理解2个RT点一定,指针的2个边缘就定了,但是笨也有笨的好处,比如2个边缘的T相差太小时甚至是T的大小检测相反时,用第二种方法还是很保险的。

 

附录:(一些关键代码)

 

“双精度”RT空间和“类非极大抑制模版”,(可以看出真正需要分配空间的是com粗化的“RT空间”)

    Rcom=(int)(((float)R)*div/com+0.5);
    Tcom=(int)(((float)T)*div/com+0.5);
 minR=(int)(((float)Rcom)/app/2+0.5);
 minT=(int)(((float)Tcom)/app/2+0.5);
    RTdata=(int **)malloc((Rcom+1)*sizeof(int *));
 for(i=Rcom;i>=0;i--)
  RTdata[i]=(int *)malloc((Tcom+1)*sizeof(int));
 for(i=0;i<=Rcom;i++)
  for(j=0;j<=Tcom;j++)
   RTdata[i][j]=0;

 

求2个RT点时,“类非极大抑制”的作用体现

    max=RTdata[n][m];
    p=n;
    q=m;
   }
    for(m=-minT;m<=minT;m++)
  for(n=-minR;n<=minR;n++)
   if(p+n>=0&&p+n<=Rcom&&q+m>=0&&q+m<=Tcom)
    RTdata[p+n][q+m]=0;

 

得到2个RT点后的选择,下面显示的是第二种比较笨的选择

 se=3;
 for(i=0;i  for(j=0;j   if(indata[i][j]==1){
    indata[i][j]=se;
    color(gap,i,j,1,se,indata,width,height);//一个同canny检测中的“染色函数”同原理的“特定条件连通域染色函数”
    se++;
   }
  }
 o=se;
    ang(p,q,div,com,3,se,indata,width,height);
 for(i=0;i  for(j=0;j   if(indata[i][j]==2){
    indata[i][j]=se;
    color(gap,i,j,2,se,indata,width,height);
    se++;
   }
  }
    ang(p1,q1,div,com,o,se,indata,width,height);

你可能感兴趣的:(算法总结——hough直线检测)