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

相關文章
相關標籤/搜索