opencv笔记(十七)——使用霍夫变换检测直线

一般我们在检测物体轮廓的时候,会有检测直线的需求,这时可以用到OpenCV当中的霍夫变换实现。

 

霍夫变换的原理的简单阐述见:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html#hough-lines

简单来讲,对于单个像素来说,它可能是由许多直线经过的,我们通过一个点可以构造无数条直线。

对于一个像素的位置(x, y),从笛卡尔坐标和极坐标两个角度,我们可以有

Line variables    y = \left ( -\dfrac{\cos \theta}{\sin \theta} \right ) x + \left ( \dfrac{r}{\sin \theta} \right )

进而得到r_{\theta} = x_{0} \cdot \cos \theta  + y_{0} \cdot \sin \theta

上式以(x, y)为自变量,r和theta为因变量。

那么对于某个(x, y),我们有无数个r和theta与之对应,见下图

Polar plot of a the family of lines of a point

对多个(x, y),我们画出他们的r和theta:

Polar plot of the family of lines for three points

由于它们的r曲线有交点,说明在某个角度theta上,他们是可以由同一条直线经过的,或者理解为他们的r-theta曲线相交。

我们再给这几个点加个限制条件:它们是相邻的点。

则在图像上看,它们就是几个相邻的点构成的一条直线。

 

OpenCV中,霍夫变换的实现有两种:HoughLines()和HoughLinesP()。后者是更有效的实现。

void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )

void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )

images为8位单通道的图,一般为Canny方法的输出(这样才是一张轮廓图嘛)

lines是输出的直线集合,一般为vector<Vec2f>类型。

rho一般为1。暂不清楚。

theta一般为CV_PI/180。暂不清楚。

threshold为我们上面所讲的r-theta曲线相交条数的最小值,也可以理解为构成直线的最少像素数。

 

 

贴一段使用霍夫变换的OpenCV代码,可以看出使用HoughLinesP比较方便:

 1 void Standard_Hough( int, void* )
 2 {
 3   vector<Vec2f> s_lines;
 4   cvtColor( edges, standard_hough, CV_GRAY2BGR );
 5 
 6   /// 1. Use Standard Hough Transform
 7   HoughLines( edges, s_lines, 1, CV_PI/180, min_threshold + s_trackbar, 0, 0 );
 8 
 9   /// Show the result
10   for( size_t i = 0; i < s_lines.size(); i++ )
11      {
12       float r = s_lines[i][0], t = s_lines[i][1];
13       double cos_t = cos(t), sin_t = sin(t);
14       double x0 = r*cos_t, y0 = r*sin_t;
15       double alpha = 1000;
16 
17        Point pt1( cvRound(x0 + alpha*(-sin_t)), cvRound(y0 + alpha*cos_t) );
18        Point pt2( cvRound(x0 - alpha*(-sin_t)), cvRound(y0 - alpha*cos_t) );
19        line( standard_hough, pt1, pt2, Scalar(255,0,0), 3, CV_AA);
20      }
21 
22    imshow( standard_name, standard_hough );
23 }
24 
25 /**
26  * @function Probabilistic_Hough
27  */
28 void Probabilistic_Hough( int, void* )
29 {
30   vector<Vec4i> p_lines;
31   cvtColor( edges, probabilistic_hough, CV_GRAY2BGR );
32 
33   /// 2. Use Probabilistic Hough Transform
34   HoughLinesP( edges, p_lines, 1, CV_PI/180, min_threshold + p_trackbar, 30, 10 );
35 
36   /// Show the result
37   for( size_t i = 0; i < p_lines.size(); i++ )
38      {
39        Vec4i l = p_lines[i];
40        line( probabilistic_hough, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,0,0), 3, CV_AA);
41      }
42 
43    imshow( probabilistic_name, probabilistic_hough );
44 }
View Code

 

-

 

posted @ 2014-12-14 17:22  nipan  阅读(821)  评论(0编辑  收藏  举报