OpenCV—HoughLines中的theta角度理解
void HoughLines( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI );
上面是 HoughLines的公式原型,其他参数都好理解,比较疑惑的是lines参数。看看头文件的描述:
Output vector of lines. Each line is represented by a two-element vector (rho, theta) . rho is the distance from the coordinate origin (0,0) (top-left corner of the image). theta is the line rotation angle in radians (0 {vertical line}, pi/2{horizontal line} ).
每条直线用一个向量表示(rho, theta),rho就是向量长度(到原点距离),theta就是直线弧度角,0{垂线},pi/2{横线}。(我理解错误了,导致全是废话)
按照上面的描述,向量在图像中应该如图所示的描述,theta=0{垂线},theta=pi/2{横线} 。
这样理解貌似不对劲,先看看这个向量是干什么用的。HoughLines这个函数主要是检测图像中的直线,结果以一些向量(rho, theta)表示,根据这些向量我们在图像上绘制出直线。这条向量其实表示的是直线的垂线,垂足就是向量的端点,如下图所示:
要绘制出真正的直线,需要找到向量的垂直向量,然后把这个垂直向量表示的直线移动到垂足位置,取这条直线上两个比较远的(超出图像边界)点绘制直线。
按照该上面的理解,计算出直线上两个点(X1,Y1)(X2,Y2)
看一下自带的案例代码:
float r = s_lines[i][0], t = s_lines[i][1];
double cos_t = cos(t), sin_t = sin(t);
double x0 = r*cos_t, y0 = r*sin_t;
double alpha = 1000;
Point pt1( cvRound(x0 + alpha*(-sin_t)), cvRound(y0 + alpha*cos_t) );
Point pt2( cvRound(x0 - alpha*(-sin_t)), cvRound(y0 - alpha*cos_t) );
line( standard_hough, pt1, pt2, Scalar(255,0,0), 3, LINE_AA);
发现计算公式跟示例代码不一致,已知示例代码运行正确,看来刚刚推算错误:
按照示例代码, theta=0{垂线},theta=pi/2{横线},这句话不对劲。应该是theta=pi/2{垂线},theta=0{横线}才对。按照这个理解重新计算一遍:
这样才跟示例代码完全匹配上。
运行代码验证一下,将示例代码改一下,把垂直线画出来,角度输出来:
for( size_t i = 0; i < s_lines.size(); i++ )
{
float r = s_lines[i][0], t = s_lines[i][1];
double cos_t = cos(t), sin_t = sin(t);
double x0 = r * cos_t, y0 = r * sin_t;
double alpha = 1000;
cout << "radian: " << t << " angle: " << t * 180 / 3.14159 << endl;
Point pt1( cvRound(x0 + alpha * (-sin_t)), cvRound(y0 + alpha * cos_t) );
Point pt2( cvRound(x0 - alpha * (-sin_t)), cvRound(y0 - alpha * cos_t) );
line( standard_hough, pt1, pt2, Scalar(255, 0, 0), 3, LINE_AA);
line( standard_hough, Point(0, 0), Point(x0, y0), Scalar(255, 255, 0), 3, LINE_AA);
}
显然下面的“line”指的是蓝色线(也就是图像真实线),theta=0{垂线},theta=pi/2{横线},这句话里的theta指的是蓝色线才能吻合起来。
theta is the line rotation angle in radians (0 {vertical line}, pi/2{horizontal line} ).
折腾了一大圈,发现是我最初就理解错了。对theta=0{垂线},theta=pi/2{横线}的理解产生了严重偏差。