霍夫变换原理及opencv实现

时间:2023-01-22 11:17:05

霍夫变换简介

霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等)。最基本的霍夫变换是从黑白图像中检测直线(线段)。———百度百科

霍夫变换检测直线原理

简单来说

首先将一条直线映射为一个点,怎么映射呢?
一种方法就是选择原点到直线的垂足,用该点来表示直线。
霍夫变换原理及opencv实现
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。

结果展示

选的图有点不好看。。。。。
霍夫变换原理及opencv实现
霍夫变换原理及opencv实现