霍夫变换直线检测
前提条件:边缘检测已经完成(单通道8位灰度图像,经过二值化变为黑白图像)
平面空间转到极坐标空间
通过上式子可以把像素点转化成极坐标,如下图所示。
上面的曲线相交与一点,说明了什么信息呢?说明这些像素都在一条直线。
比如一个图像有200个像素,通过坐标变换。那么就可以得到200条曲线。相交点的对应横坐标角度就是直线在空间坐标的角度。这就是霍夫变换的原理。
霍夫直线变换介绍:
变换到极坐标中,从[0,360]空间,可以得到r的大小
属于同一条直线上点在极坐标空间(r,θ)必然在一个点上有强的信号出现,根据此反算到平面坐标中可以得到直线上各点的像素坐标,从而得到直线。
相关API学习:
标准的霍夫变换 HoughLines从平面坐标转换到霍夫空间,最终输出(θ,r)表示极坐标空间。
霍夫变换直线斜率概率 HoughLinesP最终输出直线的两个点空间坐标。
HoughLines(
src,
dst,
double rho, //生成极坐标时候的像素扫描步长
double theta, 生成极坐标时候的角度步长,一般取值CV_P/180
int threshold, 阈值,只有获得足够交点的极坐标点才被看成是直线
double srn=0, 是否应用多尺度的霍夫变换,设置为0表示经典变换
double stn=0,
double min_theta=0,
double max_theta=CV_PI
);
HoughLines(
src,
dst,
double rho, //生成极坐标时候的像素扫描步长
double theta, 生成极坐标时候的角度步长,一般取值CV_P/180
int threshold, 阈值,只有获得足够交点的极坐标点才被看成是直线
double minLineLength = 0, 最小直线长度
double maxLineGap = 0 最大间隔像素
);
代码:
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; void help() { cout << "\nThis program demonstrates line finding with the Hough transform.\n" "Usage:\n" "./houghlines <image_name>, Default is pic1.jpg\n" << endl; } int main(int argc, char** argv) { const char* filename = argc >= 2 ? argv[1] : "1.jpg"; Mat src = imread(filename, 0); imshow("source", src); if(src.empty()) { help(); cout << "can not open " << filename << endl; return -1; } Mat dst, cdst; Canny(src, dst, 50, 200, 3); cvtColor(dst, cdst, CV_GRAY2BGR); #if 0 vector<Vec2f> lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 ); for( size_t i = 0; i < lines.size(); i++ ) { float rho = lines[i][0], theta = lines[i][1]; Point pt1, pt2; double a = cos(theta), b = sin(theta); double x0 = a*rho, y0 = b*rho; pt1.x = cvRound(x0 + 1000*(-b)); pt1.y = cvRound(y0 + 1000*(a)); pt2.x = cvRound(x0 - 1000*(-b)); pt2.y = cvRound(y0 - 1000*(a)); line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); } #else vector<Vec4i> lines; HoughLinesP(dst, lines, 1, CV_PI/180, 90, 0,2 ); for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l = lines[i]; line( src, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); } #endif imshow("detected lines", src); waitKey(); return 0; }
效果:
————————————————
版权声明:本文为CSDN博主「南山二毛」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/qq_16481211/article/details/79607896
