1. 程式人生 > >霍夫變換直線檢測基本原理hough,houghpeaks,houghlines

霍夫變換直線檢測基本原理hough,houghpeaks,houghlines

一步一步來:

1、在白紙上畫出一個直角座標系,任意給出一個點;

2、那麼,對於點(x0,y0),經過這個點的直線必定滿足y0=k*x0+b, 其中k是直線的斜率,b是直線的截距;

3、上式可以化成b=y0-k*x0,  可以看作是以-x0為斜率,以y0為截距,在k-b空間上的一個直線方程(k,b為變數);

4、可見,k-b空間上的一條直線,代表了x-y空間經過特定點的所有直線,而x-y上的特定直線責備k-b空間上的特定點表示;

利用這個原理,我們可以通過一下方法檢測可能出線的直線:

1、得到一副邊緣影象;

2、對影象中的每一個邊緣點,在k-b空間中畫出一條直線;

3、在各直線的交點,我們採取“投票”(vote)的方法,即累加:n條直線的交點,改點的值為n;

4、遍歷k-b空間,尋找出先區域性最大值(極值)的點,這些點的座標(k,b)就是影象中可能出線的直線的斜率和截距;

  為了容易理解,這裡採用了直線的斜截表達法。

  事實上這種方法並不使用,因為某些直線的斜率很大的甚至不存在。

  實際操作中,檢測直線的霍夫變換使用含極座標引數的直線表示型式,簡稱極座標式(不是極座標方程,因為還是在笛卡爾座標下表示)

其中的兩個引數的意義如下圖:

這樣,每條直線對應於theta-p空間下的一條正弦曲線,同樣採用投票求極值的方法尋找曲線

霍夫變換直線檢測的matlab實現:

這裡涉及到三個函式:hough,houghpeaks,houghlines:

1、[H,T,R] = hough(BW,'Theta',20:0.1:75)    ; (輸入二值影象BW,角度範圍與步進(最大,[-90, 90)),返回 H-霍夫空間,T-theta,R-p);

2、PEAKS = houghpeaks(H,NUMPEAKS)      ;(輸入霍夫空間和極值數量,返回極值的座標)

3、LINES=houghlines(BW,T,R,Peaks)        ; (返回lines是一個包含影象中線段首末點、p、theta的結構體)

程式碼:

I=imread('1.jpg'); 
Ihsv=rgb2hsv(I); 
Iv=Ihsv(:,:,3);%提取v空間 
Ivl=Iv(500:end,:);%擷取下半部 
Iedge=edge(Ivl,'sobel');%邊沿檢測 
Iedge = imdilate(Iedge,ones(3));%影象膨脹 %新建視窗,繪圖用 
figure (2) imshow(Iedge); hold on %左方直線檢測與繪製 
%得到霍夫空間 
[H1,T1,R1] = hough(Iedge,'Theta',20:0.1:75); 
%求極值點 Peaks=houghpeaks(H1,5); 
%得到線段資訊 
lines=houghlines(Iedge,T1,R1,Peaks);
%繪製線段 
for k=1:length(lines) 
 xy=[lines(k).point1;
 lines(k).point2]; 
 plot(xy(:,1),xy(:,2),'LineWidth',4); 
end 
%右方直線檢測與繪製 
[H2,T2,R2] = hough(Iedge,'Theta',-75:0.1:-20);
Peaks1=houghpeaks(H2,5); 
lines1=houghlines(Iedge,T2,R2,Peaks1);
for k=1:length(lines1) 
 xy1=[lines1(k).point1;lines1(k).point2];
 plot(xy1(:,1),xy1(:,2),'LineWidth',4);
end
hold off
輸入影象:

  輸出影象: