hough變換找直線 matlab下能直接執行
先看效果,左上角為原圖,左下角為找到的直線,右圖為hough變換後的圖
clc;
clear;
i=imread('');
imshow(i)
figure
i=rgb2gray(i);
i_hight=size(i,1);
i_width=size(i,2);
% i_edge=edge(i,'robert');
i_hough=zeros(600,360);
for y=1:i_hight
for x=1:i_width
if i(y,x)==0 %座標系轉換
for l=1:360
r=x*cos(l*pi/180)+y*sin(l*pi/180);
w=fix(r)+300; %修正為正整數
i_hough(w,l)=i_hough(w,l)+1;
endendendendm=max(max(i_hough));
i_hough=(i_hough./m); %亮度調整
threshold=0.75; %設定直線亮度閾值
ih_hight=size(i_hough,1);
ih_width=size(i_hough,2);
temp=zeros(20,20);
count=0;
for y=1:ih_hight %找那些亮度高的直線
for x=1:ih_width/2
if i_hough(y,x)>threshold
count = count+1;
temp(count,1) = x;
temp(count,2) = y;
endendendimshow(i)
hold on
for i=1:count %畫呀話
% y=kx+b
k = tan(temp(i,1)*pi/180);
b = (temp(i,2)-300)/sin(temp(i,1)*pi/180);
for j=1:360
x(j)=j;
y(j)=-x(j)/k+b;
endplot(x,y)
hold on
endaxis equal
figure
imshow(i_hough)
下面的是理論
hough變換用來在圖象中查詢直線。它的原理很簡單:
直線上的每一點都滿足法線方程p=x*cosθ+y*sinθ (1),
p是直線座標系的原點到直線的距離,θ是直線l的垂線與x軸的夾角。
圖象x-y空間的一條直線和極座標空間o-pθ中的一點有著一一對應的關係。
注意這個一一對應,即x-y空間中的一點也對應這極座標空間中的一條曲線(可以看作xy空間中的特徵引數來表示一條直線)
利用這個事實,我們可以找出某條直線來。
經典hough變換的方法是根據要求的精度將o-pθ空間量化為許多小格,每個小格是乙個累加器。
對於圖象空間x-y中的每一點,按照法向方程在o-pθ平面中得到它所對應的曲線,凡是這條曲線經過的小格,其累加器加1.即投票。
由於通過同一小格的曲線所對應的點近乎共線,於是小格的累加器數值等於共線的點數。當完成全部變換後,對所有累加器的數值進行校驗,
票數多的小格對應與引數空間(p,θ)的共線點,其(p,θ)是圖象空間的直線擬合引數。得票小的小格反映著非共線點,丟棄不用。這種體制體現了hough變換康干擾的魯棒性。
從以上過程可以看出,若(p,θ)網格量化過小,雖然擬合直線的引數可以準確求出,但計算量明顯加大,且各組共線點可能變少;
反之,引數空間的集聚效果差,找不到準確描述圖象空間的(p,θ)引數,因此要適當選取網格大小。---這就是θ選用2度為乙個步長
由此可見,hough變換的基本策略是:由影象空間中的邊緣資料點去計算引數空間中的引數點的可能軌跡,並在乙個累加器中給計算出的參考點計數,最後選出峰值。
hough變換法主要優點是受共線點的間隙和雜訊影響較小。
對於雷射測距儀採集的一幀資料進行哈夫變換處理可將資料點集按線段分成若干簇。
直線的方程可以用y=k*x+b 來表示,其中k和b是引數,分別是斜率和截距。過某一點(x0,y0)的
所有直線的引數都會滿足方程y0=kx0+b。即點(x0,y0)確定了一族直線。方程y0=kx0+b在引數k--b平
面上是一條直線。這樣,影象x--y平面上的乙個前景畫素點就對應到引數平面上的一條直線。
舉個例子說明解決前面那個問題的原理。設影象上的直線是y=x, 我們先取上面的三個點:a(0,0)
, b(1,1), c(22)。可以求出,過a點的直線的引數要滿足方程b=0, 過b點的直線的引數要滿足方程
1=k+b, 過c點的直線的引數要滿足方程2=2k+b, 這三個方程就對應著引數平面上的三條直線,而這三
條直線會相交於一點(k=1,b=0)。 同理,原影象上直線y=x上的其它點(如(3,3),(4,4)等) 對應引數
平面上的直線也會通過點(k=1,b=0)。這個性質就為解決問題提供了方法:
首先,初始化一塊緩衝區,對應於引數平面,將其所有資料置為0.對於影象上每一前景點,求出參
數平面對應的直線,把這直線上的所有點的值都加1。最後,找到引數平面上最大點的位置,這個位置
就是原影象上直線的引數。
上面就是霍夫變換的基本思想。就是把影象平面上的點對應到引數平面上的線,最後通過統計特性來
解決問題。假如影象平面上有兩條直線,那麼最終在引數平面上就會看到兩個峰值點,依此類推。
在實際應用中,y=k*x+b形式的直線方程沒有辦法表示x=c形式的直線(這時候,直線的斜率為無窮大)。
所以實際應用中,是採用引數方程p=x*cos(theta)+y*sin(theta)。這樣,影象平面上的乙個點就對應到
引數p---theta平面上的一條曲線上。其它的還是一樣。
下面是修改版,防止出現同一條直線被認作是多條直線的情況
clc;
clear;
img=imread('');
% imshow(img)
% figure
img=rgb2gray(img);
i_hight=size(img,1);
i_width=size(img,2);
% i_edge=edge(img,'robert');
% figure
% imshow(img)
i_hough=zeros(800,360);
for y=1:i_hight
for x=1:i_width
if img(y,x)==0 %座標系轉換
for l=1:360
r=x*cos(l*pi/180)+y*sin(l*pi/180);
w=fix(r)+400; %修正為正整數
i_hough(w,l)=i_hough(w,l)+1;
endendendendm=max(max(i_hough));
i_hough=(i_hough./m); %亮度調整
figure
imshow(i_hough)
threshold=0.50設定直線亮度閾值
ih_hight=size(i_hough,1);
ih_width=size(i_hough,2);
temp=zeros(100,2);
count=0;
for y=1:ih_hight %找那些亮度高的直線
for x=1:ih_width/2
if i_hough(y,x)>threshold
count = count+1;
temp(count,1) = x;
temp(count,2) = y;
endendend% 調和高亮點
while(1)
flag = 0;
for i=1:count
if flag==0
for j=i+1:count
dis = sqrt((temp(i,1)-temp(j,1))^2 + (temp(i,2)-temp(j,2))^2);
if dis<50調和半徑
flag = 1;
temp(i,1)=(temp(i,1)+temp(j,1))/2;
temp(i,2)=(temp(i,2)+temp(j,2))/2;
temp(j,:)=;
count = count-1;
break;
endendendendif flag == 0
break;
endendfigure
imshow(img)
hold on
for i=1:count %畫呀話
% y=kx+b
k = tan(temp(i,1)*pi/180);
b = (temp(i,2)-400)/sin(temp(i,1)*pi/180); %-400是為了反修正
for j=1:360
x(j)=j;
y(j)=-x(j)/k+b;
endplot(x,y)
hold on
endaxis equal
axis([0,400,0,400]);
基於霍夫變換的分段檢測
6 中所介紹的的快速霍夫變換,是通過等級逼近解決方案的的方法來完成的。執行這一過程所運用的方法允許免除引數空間的投票累計。然而,這種演算法仍然存在點冗餘,縮放,錯誤的解決方案,不同尺寸的點檢測等問題。在這篇 中,我們將要為fht的計算提出乙個新的演算法,這個演算法能圓滿的解決以上所提出的的演算法中所...
基爾霍夫定律實踐教改
摘要 電工基礎 是廣廈學院對數控技術專業的一門實踐性很強的專業基礎課,根據學院職業崗位的核心知識能力要求,以 理論夠用 適度,強化技能培養 為原則,在課程的建設過程中,專業教師不斷努力進行實踐教學改革,目前取得了一定的成效,同學們的學習接受能力 學習主動性和實踐能力均得到了很大的提高。關鍵詞 電工基...
基爾霍夫定律說課
今天的說課,我想從以下七個方面來進行,其中說構思是我們今天說課的重點 一 說教材 本課題取自於由汪濤何鐵男主編 國防工業出版社 電工技術與實訓 中的第一章第二節。掌握基爾霍夫定律是分析電路的基礎,在整本教材中佔據著舉足輕重的作用 基爾霍夫定律是主要電學定律之一,其掌握與靈活運用由為重要,是我們解決複...