Hough 圆变换----Matlab实现
生活随笔
收集整理的這篇文章主要介紹了
Hough 圆变换----Matlab实现
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?
霍夫變換(Hough)是一個(gè)非常重要的檢測(cè)間斷點(diǎn)邊界形狀的方法。它通過(guò)將圖像坐標(biāo)空間變換到參數(shù)空間,來(lái)實(shí)現(xiàn)直線與曲線的擬合。
參數(shù)空間可以表示為(a,b,r),圖像坐標(biāo)空間中的一個(gè)圓對(duì)應(yīng)參數(shù)空間中的一個(gè)點(diǎn)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?A(a,b,r)。
計(jì)算過(guò)程是讓a,b在取值范圍內(nèi)增加,解出滿足上式的r值,每計(jì)算出一個(gè)(a,b,r)值,就對(duì)相應(yīng)的數(shù)組元素A(a,b,r)加1。計(jì)算結(jié)束后,找到的超過(guò)閾值的A(a,b,r)所對(duì)應(yīng)的a,b,r就是所求的圓的參數(shù)。
?
函數(shù)程序:
?
?
function?[Hough_space,Hough_circle_result,Para]?=?Hough_circle(BW,Step_r,Step_angle,r_min,r_max,p)?? %---------------------------------------------------------------------------------------------------------------------------?? %?input:?? %?BW:二值圖像;?? %?Step_r:檢測(cè)的圓半徑步長(zhǎng);?? %?Step_angle:角度步長(zhǎng),單位為弧度;?? %?r_min:最小圓半徑;?? %?r_max:最大圓半徑;?? %?p:以p*Hough_space的最大值為閾值,p取0,1之間的數(shù).?? %?a?=?x-r*cos(angle);?b?=?y-r*sin(angle);?? %---------------------------------------------------------------------------------------------------------------------------?? %?output:?? %?Hough_space:參數(shù)空間,h(a,b,r)表示圓心在(a,b)半徑為r的圓上的點(diǎn)數(shù);?? %?Hough_circle:二值圖像,檢測(cè)到的圓;?? %?Para:檢測(cè)到的圓的圓心、半徑.?? %---------------------------------------------------------------------------------------------------------------------------?? circleParaXYR=[];?? Para=[];?? %得到二值圖像大小?? [m,n]?=?size(BW);?? %計(jì)算檢測(cè)半徑和角度的步數(shù)、循環(huán)次數(shù)?并取整,四舍五入?? size_r?=?round((r_max-r_min)/Step_r)+1;?? size_angle?=?round(2*pi/Step_angle);?? %建立參數(shù)空間?? Hough_space?=?zeros(m,n,size_r);?? %查找非零元素的行列坐標(biāo)?? [rows,cols]?=?find(BW);?? %非零坐標(biāo)的個(gè)數(shù)?? ecount?=?size(rows);?? %?Hough變換?? %?將圖像空間(x,y)對(duì)應(yīng)到參數(shù)空間(a,b,r)?? %?a?=?x-r*cos(angle)?? %?b?=?y-r*sin(angle)?? for?i=1:ecount??for?r=1:size_r?%半徑步長(zhǎng)數(shù)按一定弧度把圓幾等分??for?k=1:size_angle??a?=?round(rows(i)-(r_min+(r-1)*Step_r)*cos(k*Step_angle));??b?=?round(cols(i)-(r_min+(r-1)*Step_r)*sin(k*Step_angle));??if?(a>0&&a<=m&&b>0&&b<=n)??Hough_space(a,b,r)=Hough_space(a,b,r)+1;%h(a,b,r)的坐標(biāo),圓心和半徑??end??end??end?? end?? %?搜索超過(guò)閾值的聚集點(diǎn),對(duì)于多個(gè)圓的檢測(cè),閾值要設(shè)的小一點(diǎn)!通過(guò)調(diào)此值,可以求出所有圓的圓心和半徑返回值就是這個(gè)矩陣的最大值?? max_para?=?max(max(max(Hough_space)));?? %一個(gè)矩陣中,想找到其中大于max_para*p數(shù)的位置?? index?=?find(Hough_space>=max_para*p);?? length?=?size(index);%符合閾值的個(gè)數(shù)?? Hough_circle_result=zeros(m,n);?? %通過(guò)位置求半徑和圓心。?? for?i=1:ecount??for?k=1:length??par3?=?floor(index(k)/(m*n))+1;??par2?=?floor((index(k)-(par3-1)*(m*n))/m)+1;??par1?=?index(k)-(par3-1)*(m*n)-(par2-1)*m;??if((rows(i)-par1)^2+(cols(i)-par2)^2<(r_min+(par3-1)*Step_r)^2+5&&...??(rows(i)-par1)^2+(cols(i)-par2)^2>(r_min+(par3-1)*Step_r)^2-5)??Hough_circle_result(rows(i),cols(i))?=?1;%檢測(cè)的圓??end??end?? end?? %?從超過(guò)峰值閾值中得到???? for?k=1:length????par3?=?floor(index(k)/(m*n))+1;%取整????par2?=?floor((index(k)-(par3-1)*(m*n))/m)+1;????par1?=?index(k)-(par3-1)*(m*n)-(par2-1)*m;????circleParaXYR?=?[circleParaXYR;par1,par2,par3];????Hough_circle_result(par1,par2)=?1;?%這時(shí)得到好多圓心和半徑,不同的圓的圓心處聚集好多點(diǎn),這是因?yàn)樗o的圓不是標(biāo)準(zhǔn)的圓???? end??? %集中在各個(gè)圓的圓心處的點(diǎn)取平均,得到針對(duì)每個(gè)圓的精確圓心和半徑;?? while?size(circleParaXYR,1)?>=?1??num=1;??XYR=[];??temp1=circleParaXYR(1,1);??temp2=circleParaXYR(1,2);??temp3=circleParaXYR(1,3);??c1=temp1;??c2=temp2;??c3=temp3;??temp3=?r_min+(temp3-1)*Step_r;??if?size(circleParaXYR,1)>1??for?k=2:size(circleParaXYR,1)??if?(circleParaXYR(k,1)-temp1)^2+(circleParaXYR(k,2)-temp2)^2?>?temp3^2??XYR=[XYR;circleParaXYR(k,1),circleParaXYR(k,2),circleParaXYR(k,3)];??%保存剩下圓的圓心和半徑位置??else??c1=c1+circleParaXYR(k,1);??c2=c2+circleParaXYR(k,2);??c3=c3+circleParaXYR(k,3);??num=num+1;??end??end??end??c1=round(c1/num);??c2=round(c2/num);??c3=round(c3/num);??c3=r_min+(c3-1)*Step_r;??Para=[Para;c1,c2,c3];?%保存各個(gè)圓的圓心和半徑的值??circleParaXYR=XYR;?? end ??
主程序:
clc?? clear?all?? %------------------------------------------------------------------------------?? %模擬圖像?? I=ones(256,256);?? I(20:20:220,20:20:220)=0;?? for?i=20:20:220??for?j=20:20:220??circle_size=floor(rand*4);??for?ci=i-circle_size:i+circle_size??for?cj=j-circle_size:j+circle_size??if?(ci-i)^2+(cj-j)^2<circle_size^2??I(ci,cj)=0;??end??end??end??end?? end?? I=?imgaussfilt(I,?4);?? I(I>0.9)=1;?? I(I<0.9)=0;?? %---------------------------------------------------------------------------------?? %加入直線干擾?? I(64,:)=0;I(:,64)=0;I(128,:)=0;I(:,128)=0;I(192,:)=0;I(:,192)=0;?? figure(1);?? imshow(I,[]),title('原圖');?? %---------------------------------------------------------------------------------?? %?用sobel進(jìn)行邊緣檢測(cè)?? BW?=?edge(I,'sobel');?? %---------------------------------------------------------------------------------?? %設(shè)置參數(shù):?? %檢測(cè)的圓半徑步長(zhǎng)為1?? Step_r?=?0.5;?? %角度步長(zhǎng)0.1,單位為弧度?? Step_angle?=?0.1;?? %最小圓半徑2?? minr?=5;?? %最大圓半徑30?? maxr?=?20;?? %以thresh*hough_space的最大值為閾值,thresh取0-1之間的數(shù)?? thresh?=?0.8;?? circleParaXYR=[];?? %---------------------------------------------------------------------------------?? %開(kāi)始檢測(cè)?? [Hough_space,Hough_circle_result,Para]?=?Hough_circle(BW,Step_r,Step_angle,minr,maxr,thresh);?? circleParaXYR=Para;?? axis?equal?? figure(2);?? imshow(BW,[]),title('邊緣');?? axis?equal?? figure(3);?? imshow(Hough_circle_result,[]),title('檢測(cè)結(jié)果');?? axis?equal?? figure(4),imshow(I,[]),title('檢測(cè)出圖中的圓')?? hold?on;?? %---------------------------------------------------------------------------------?? %以紅色線標(biāo)記出的檢測(cè)圓心與圓?? plot(circleParaXYR(:,2),?circleParaXYR(:,1),?'r+');?? for?k?=?1?:?size(circleParaXYR,?1)??t=0:0.01*pi:2*pi;??x=cos(t).*circleParaXYR(3,k)+circleParaXYR(2,k);??y=sin(t).*circleParaXYR(3,k)+circleParaXYR(1,k);??plot(x,y,'r-');?? end ??
如有問(wèn)題請(qǐng)留言。
總結(jié)
以上是生活随笔為你收集整理的Hough 圆变换----Matlab实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 我家的漫路超市——怎么开淘宝网店
- 下一篇: 3D曲面可视化