hough变换算法

1、算法思想

边缘检测好比canny算子能够识别出图像的边缘,可是实际中因为噪声和光照不均匀等因素,不少状况下得到的边缘点是不连续的,必须经过边缘链接将他们转换为有意义的边缘。Hough变化是一个重要的检测间断点边界形状的方法,它经过将图像坐标空间变化到参数空间来实现直线和曲线的拟合。php

霍夫变换于1962年由Paul Hough 首次提出,后于1972年由Richard Duda和Peter Hart推广使用,经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。html

Hough变换是图像处理中从图像中识别几何形状的基本方法之一。Hough直线检测的基本原理在于利用点与线的对偶性,在咱们的直线检测任务中,即图像空间中的直线与参数空间中的点是一一对应的,参数空间中的直线与图像空间中的点也是一一对应的。这意味着咱们能够得出两个很是有用的结论:算法

1)图像空间中的每条直线在参数空间中都对应着单独一个点来表示;数组

2)图像空间中的直线上任何一部分线段在参数空间对应的是同一个点。函数

所以Hough直线检测算法就是把在图像空间中的直线检测问题转换到参数空间中对点的检测问题,经过在参数空间里寻找峰值来完成直线检测任务,也即把检测总体特性转化为检测局部特性。测试

 2、算法原理

1)图像空间和参数空间spa

霍夫变换的数学理解是“换位思考”,好比一条直线y=a*x+b有两个参数,在给定坐标系下,这条直线就能够用a和b进行完整的表述。若是咱们把x和y看做参数,把a和b看做变量的话,那么图像空间下的坐标点(x1,y1)对应着参数空间里的一条直线q=-x1*k+y1, 图像空间直线上的点(x1,y1)就是参数空间的斜率和截距,其中k,q为参数空间的自变量。.net

2)参数空间转换过程3d

下面用不一样空间下的点和线的变换过程示例说明。code

一条直线可由两个点A=(X1,Y1)和B=(X2,Y2)肯定(笛卡尔坐标)。

 另外一方面,y=kx+q也能够写成关于(k,q)的函数表达式(霍夫空间):

对应的变换能够经过图形直观表示:

变换后的空间成为霍夫空间。即:笛卡尔坐标系中一条直线,对应霍夫空间的一个点

反过来一样成立(霍夫空间的一条直线,对应笛卡尔坐标系的一个点):

再来看看A、B两个点,对应霍夫空间的情形:

 再看一下三个点共线的状况:

能够看出若是笛卡尔坐标系的点共线,这些点在霍夫空间对应的直线交于一点:这也是必然,共线只有一种取值可能。

若是不止一条直线呢?再看看多个点的状况(有两条直线):

 其实(3,2)与(4,1)也能够组成直线,只不过它有两个点肯定,而图中A、B两点是由三条直线汇成,这也是霍夫变换的后处理的基本方式选择由尽量多直线汇成的点

  到这里问题彷佛解决了,已经完成了霍夫变换的求解,可是若是像下图这种状况呢?

 k=∞是不方便表示的,并且q怎么取值呢,这样不是办法。所以考虑将笛卡尔坐标系换为:极坐标表示。(参考文件里大佬博客里面的图错了,下图是正确的极坐标表示方法,而且给出了辅助线几何解释)

 在极坐标系下,实际上是同样的:极坐标的点→霍夫空间的直线,只不过霍夫空间再也不是[k,q]的参数,而是[ρ, θ]的参数,给出对比图:

 

从上面能够看到,参数空间的每一个点)都对应了图像空间的一条直线,或者说图像空间的一个点在参数空间中就对应为一条曲线。这样就把在图像空间中检测直线的问题转化为在极坐标参数空间中找经过点(r,θ)的最多正弦曲线数的问题。霍夫空间中,曲线的交点次数越多,所表明的参数越肯定,画出的图形越饱满。

霍夫直线检测就是把图像空间中的直线变换到参数空间中的点,经过统计特性来解决检测问题。具体来讲,若是一幅图像中的像素构成一条直线,那么这些像素坐标值(x, y)在参数空间对应的曲线必定相交于一个点,因此咱们只须要将图像中的全部像素点(坐标值)变换成参数空间的曲线,并在参数空间检测曲线交点就能够肯定直线了。

下面给出霍夫变换的算法步骤:

 总结:使用霍夫变换检测直线具体步骤:

1.彩色图像->灰度图

2.去噪(高斯核)

3.边缘提取(梯度算子、拉普拉斯算子、canny、sobel)

4.二值化(判断此处是否为边缘点,就看灰度值==255)

5.映射到霍夫空间(准备两个容器,一个用来展现hough-space概况,一个数组hough-space用来储存voting的值,由于投票过程每每有某个极大值超过阈值,多达几千,不能直接用灰度图来记录投票信息)

6.取局部极大值,设定阈值,过滤干扰直线

7.绘制直线、标定角点

三、代码测试

函数原型:

CV_EXPORTS_W 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 );

 测试代码以下:

int main() {
    Mat src_img;
    Mat dst_img, cdst, cdst2;

    src_img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic18.bmp");
    imshow("原图", src_img);
    
    Canny(src_img, dst_img, 50, 200, 3);
    imshow("Canny图", dst_img);


    cdst = src_img.clone();
    cdst2 = dst_img.clone();
    vector<Vec2f> lines;
    HoughLines(dst_img, 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), 1, LINE_AA);
        line(cdst2, pt1, pt2, Scalar(255, 255, 255), 1, LINE_AA);
    }

    imshow("detected lines", cdst);
    imshow("detected lines2", cdst2);

    waitKey(0);
}

测试效果图以下,canny边缘检测有不连续的边缘,霍夫变换直线检测能够链接不连续的直线边缘。

四、参考文献

一、《数字图像处理与机器视觉》

第二版。 张铮、徐超、任淑霞、韩海玲等编著。

二、霍夫变换直线检测(Line Detection)原理及示例

http://www.javashuo.com/article/p-rpdffoyo-hq.html

三、霍夫变换

http://www.javashuo.com/article/p-twdgbvsy-dc.html

四、霍夫变换-----特征提取

http://www.javashuo.com/article/p-bkxnyfjo-hm.html

五、霍夫线变换

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html

六、霍夫圆变换

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html

七、经典霍夫变换(Hough Transform)

http://www.javashuo.com/article/p-dibtcufo-kx.html

八、霍夫变换(Hough Transform)的原理以及代码(Matlab&C)实现

http://www.javashuo.com/article/p-shbddnmj-hm.html

 

我的博客,转载请注明。

 http://www.javashuo.com/article/p-gnasbybj-cn.html

相关文章
相关标签/搜索