opencv笔记(十七)——使用霍夫变换检测直线
一般我们在检测物体轮廓的时候,会有检测直线的需求,这时可以用到OpenCV当中的霍夫变换实现。
霍夫变换的原理的简单阐述见:http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html#hough-lines
简单来讲,对于单个像素来说,它可能是由许多直线经过的,我们通过一个点可以构造无数条直线。
对于一个像素的位置(x, y),从笛卡尔坐标和极坐标两个角度,我们可以有
进而得到
上式以(x, y)为自变量,r和theta为因变量。
那么对于某个(x, y),我们有无数个r和theta与之对应,见下图
对多个(x, y),我们画出他们的r和theta:
由于它们的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 }
-