Hough Transform直線檢測


本文原創,如轉載請注明出處。

 

Hough Transform 是一種能提取圖像中某種特定形狀特征的方法,可以將其描述成一種把圖像空間中的像素轉換成Hough空間中直線或曲線的一種映射函數。通過利用Hough空間的一些性質,我們可以找到並識別一些有共同特性的點(如在同一條直線上)。這樣我們就得到足夠的信息去畫出這些圖形(如直線)。其輸入圖像通常為二值邊緣圖像。

1.原理:

圖像空間是所有像素所屬於的圖像的空間。Hough空間是一種變量混合空間,實際上它與圖像相關但是卻不存在物理實質性。

我們可以把圖像空間的坐標通過下式表達成Hough空間:

X = Ρ·cosΘ

Y = Ρ·sinΘ

where

 P = sqrt(x2+y2) ,  是坐標原點到直線的距離

  ,是距離與x坐標軸的夾角

通常我們寫成如下形式:    

通過下圖我們可以更加容易理解上述式子:

經過Hough變換我們將圖像空間中的一個點映射到Hough空間,如下圖我們得到了一條正弦曲線。

在這里正弦曲線的形狀取決於,點到我們所定義原點的距離。通常,距離越大,正弦曲線的振幅越大,反之則會變小。為了使曲線顯示我們把縱坐標設置成如上,當然我也可以用π表示。

以同樣的方法我們可以再次映射一個點,而我們知道在圖像空間中兩個點總在一條直線上。而在Hough空間中我們可以看到兩條正弦曲線可能會相交如下圖:

 

在這里我們可以把每一個交點看成是一次投票,也就是

計算完所有邊緣點后,我們可以設置一個閾值,投票大於這個閾值的點這是我們要找的直線。如下分別為原圖,閾值為30,20時候檢測到的直線。

   

對於大於閾值的點我們有其Hough space的參數對(p,Θ), 通過逆映射我們可以得到圖像空間中的直線:

 

 2.opencv示例:

步驟如下:

1.載入圖像

2.應用canny或其他邊緣檢測算子得到邊緣的二值圖像

3.應用Hough transform(Houghline())

4.在原圖像上畫出直線

void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )

 

 1 #include "opencv2/highgui/highgui.hpp"
 2 #include "opencv2/imgproc/imgproc.hpp"
 3 #include <iostream>
 4  
 5 using namespace cv;
 6 using namespace std;
 7  
 8 int main()
 9 {
10     Mat src = imread("building.jpg", 0);
11  
12     Mat dst, cdst;
13     Canny(src, dst, 50, 200, 3); 
14     cvtColor(dst, cdst, CV_GRAY2BGR); 
15  
16     vector<Vec2f> lines;
17     // detect lines
18     HoughLines(dst, lines, 1, CV_PI/180, 150, 0, 0 );
19  
20     // draw lines
21     for( size_t i = 0; i < lines.size(); i++ )
22     {
23         float rho = lines[i][0], theta = lines[i][1];
24         Point pt1, pt2;
25         double a = cos(theta), b = sin(theta);
26         double x0 = a*rho, y0 = b*rho;
27         pt1.x = cvRound(x0 + 1000*(-b));
28         pt1.y = cvRound(y0 + 1000*(a));
29         pt2.x = cvRound(x0 - 1000*(-b));
30         pt2.y = cvRound(y0 - 1000*(a));
31         line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
32     }
33  
34     imshow("source", src);
35     imshow("detected lines", cdst);
36  
37     waitKey();
38     return 0;
39 }

結果:

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM