霍夫变换简介
霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等)。最基本的霍夫变换是从黑白图像中检测直线(线段)。———百度百科
霍夫变换检测直线原理
简单来说
首先将一条直线映射为一个点,怎么映射呢?
一种方法就是选择原点到直线的垂足,用该点来表示直线。
rho,theta这两个参数决定了一条直线,这就相当 与映射到极坐标了。
这种线到点的变换就是霍夫变换。
那么接着想,如果是过任一点(x0,y0)的直线系,按照上述方法映射到极坐标
r = cos(theta)*x0 + sin(theta)*y0=(x^2+y^2)^(1/2)sin(theta+f)
f=arctan(y0/x0)
没错过一点的直线系在极坐标里映射成了正弦曲线。
接着如果一些点能练成直线,那么过这些点的直线系所对应的正弦曲线必交于一点。这样这个点对应直角坐标系的这些点所连成直线。完成识别。
霍夫变换检测直线算法
1.如何知道这些正弦曲线公共交点呢,我们可以将rho,theta这两个参数取值范围等分成m,n分,用一个二维数组来装。
2.对于图像边缘中的每一点看成直线系映射到极坐标成为正弦曲线,然后用一个变量比如theta,求出每个取值后对应的rho,然后落入的二维数组的分组中加1,以此类推。
3.当遍历所有的点后,二维数组最高的值或过阈值的值,其数组的坐标即为直角坐标检测出的直线。
4.m、n划分越细越精确,但运算量大。反之亦然。
霍夫变换检测直线实现
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat image = imread("D:\\乱\\1.jpg");
Mat result;
cvtColor(image,result,CV_BGR2GRAY);
Mat contours;
Canny(result, contours, 125, 350);
vector<Vec2f> lines;
HoughLines(contours, lines, 1, CV_PI / 180, 100);
vector<Vec2f>::const_iterator it = lines.begin();
cout << lines.size() << endl;
printf("OK");
while (it != lines.end())
{
printf("OK");
float r = (*it)[0];
float theta = (*it)[1];
double a = cos(theta), b = sin(theta);
double x0 = a*r, y0 = b*r;
Point pt1(cvRound(x0 + 1000 * (-b)),
cvRound(y0 + 1000 * (a)));
Point pt2(cvRound(x0 - 1000 * (-b)),
cvRound(y0 - 1000 * (a)));
line(image, pt1, pt2, Scalar(0, 0, 255), 3, 8);
it++;
}
printf("OK");
namedWindow("houghline");
imshow("houghline", image);
waitKey(0);
}
1000怎么来的 简单解释一下,画图时两点确定一条直线,我们去距垂足那个点上下1000单位的两个点来画直线,当然500也行,官方示例代码给1000。
结果展示
选的图有点不好看。。。。。