引言
本文講述霍夫變換的一些內(nèi)容,并加入一些理解性東西,參考了部分博客等相關(guān)性?xún)?nèi)容。希望能對(duì)霍夫變換有所了解,也希望看到的人如果發(fā)現(xiàn)錯(cuò)誤及時(shí)幫忙糾正。博主水平有限,還望賜教。
歷史和簡(jiǎn)介
歷史
霍夫變換(Hough Transform)是在1959年由氣泡室(Bubble Chamber)照片的機(jī)器分析而發(fā)明,發(fā)明者Paul Hough在1962年獲得美國(guó)專(zhuān)利,被命名為Method and Means for Recognizing Complex Patterns(用于識(shí)別復(fù)雜圖案的方法和手段)。該專(zhuān)利對(duì)直線(xiàn)采用斜截距參數(shù)化,但由于斜率可能變成無(wú)窮大,這有可能導(dǎo)致無(wú)限變換空間(unbounded transform space)。
現(xiàn)在使用的霍夫變換是1972年由Richard Duda和Peter Hart所發(fā)明,稱(chēng)為“廣義霍夫變換[GHT]”(Use of the Hough Transformation to Detect Lines and Curves in Pictures,1972)。
然后1981年在Dana H. Ballard的計(jì)算機(jī)視覺(jué)社區(qū)中出現(xiàn)一篇文章名為 Generalizing the Hough transform to detect arbitrary shapes,從而推廣開(kāi)來(lái)。
該文描述了使用模板匹配原理對(duì)霍夫變換進(jìn)行修改。要知道霍夫變換最初是為了分析定義的形狀(如線(xiàn)、圓、橢圓等)而開(kāi)發(fā)。通過(guò)了解其形狀并旨在其找出圖像中的位置和方向,這種改變使得霍夫變換能夠檢測(cè)用其模型描述的任意對(duì)象。這將圖像中查找對(duì)象(用模型描述)的問(wèn)題通過(guò)查找模型在圖像中的位置來(lái)解決。利用廣義霍夫變換(GHT),找到模型位置的問(wèn)題轉(zhuǎn)換為尋找將模型映射到圖像中的變換參數(shù)的問(wèn)題。給定變換參數(shù)的值,就可以確定模型在圖像中的位置。
后來(lái)產(chǎn)生了更多霍夫變換的變體和擴(kuò)展,比如KHT,3DKHT,這里不細(xì)致說(shuō)明。
簡(jiǎn)介
霍夫變換是一個(gè)特征提取技術(shù)。其可用于隔離圖像中特定形狀的特征的技術(shù),應(yīng)用在圖像分析、計(jì)算機(jī)視覺(jué)和數(shù)字圖像處理領(lǐng)域。目的是通過(guò)投票程序在特定類(lèi)型的形狀內(nèi)找到對(duì)象的不完美實(shí)例。這個(gè)投票程序是在一個(gè)參數(shù)空間中進(jìn)行的,在這個(gè)參數(shù)空間中,候選對(duì)象被當(dāng)作所謂的累加器空間中的局部最大值來(lái)獲得,所述累加器空間由用于計(jì)算霍夫變換的算法明確地構(gòu)建。最基本的霍夫變換是從黑白圖像中檢測(cè)直線(xiàn)(線(xiàn)段)。Hough變換主要優(yōu)點(diǎn)是能容忍特征邊界描述中的間隙,并且相對(duì)不受圖像噪聲的影響。
原理
霍夫變換最簡(jiǎn)單的是檢測(cè)直線(xiàn)。我們知道,直線(xiàn)的方程表示可以由斜率和截距表示(這種表示方法,稱(chēng)為斜截式),如下所示:
如果用參數(shù)空間表示則為,即用斜率和截距就能表示一條直線(xiàn)。
但是這樣會(huì)參數(shù)問(wèn)題,垂直線(xiàn)的斜率不存在(或無(wú)限大),這使得斜率參數(shù)的值接近于無(wú)限。為此,為了更好的計(jì)算,Richard O. Duda和Peter E. Hart在1971年4月,提出了Hesse normal form(Hesse法線(xiàn)式)
其中是原點(diǎn)到直線(xiàn)上最近點(diǎn)的距離(其他人可能把這記錄為,下面也可以把r看成參數(shù)),是軸與連接原點(diǎn)和最近點(diǎn)直線(xiàn)之間的夾角。如圖1所示。
圖1
因此,可以將圖像的每一條直線(xiàn)與一對(duì)參數(shù)相關(guān)聯(lián)。這個(gè)參數(shù)平面有時(shí)被稱(chēng)為霍夫空間,用于二維直線(xiàn)的集合。
在概念上,霍夫變換很接近Radon變換有人將之看成同一變換的不同形式
經(jīng)過(guò)Hough變換,將圖像空間中的一個(gè)點(diǎn)映射到Hough空間,如圖2所示。
圖2
圖2:固定一個(gè)點(diǎn)(3,4),在角度取時(shí),r的取值范圍情況. 該圖是用matlab繪制,代碼如下
% 一個(gè)點(diǎn)的坐標(biāo)為(3,4)
x=3;
y=4;
%將給定的一個(gè)定點(diǎn)映射到霍夫變換空間
theta=0:pi/200:2*pi;% 角度
r=x*cos(theta)+y*sin(theta);
plot(theta,r);%繪圖
set(gca,‘XTick’,[0:pi/10:2*pi]); % 修改x軸坐標(biāo)間隔
xlabel(‘變量 heta’)
ylabel(‘變量r’)繼續(xù)正題內(nèi)容,圖2顯示了經(jīng)過(guò)定點(diǎn)時(shí)的關(guān)系。顯示了在極坐標(biāo)對(duì)極徑極角平面繪出所有通過(guò)該定點(diǎn)的直線(xiàn), 將得到一條正弦曲線(xiàn)。正弦曲線(xiàn)的形狀取決于,點(diǎn)到所定義原點(diǎn)的距離。通常,越大,正弦曲線(xiàn)的振幅越大,反之則會(huì)越小。
所以我們可以得到一個(gè)結(jié)論,給定平面中的單個(gè)點(diǎn),那么通過(guò)該點(diǎn)的所有直線(xiàn)的集合對(duì)應(yīng)于平面中的正弦曲線(xiàn),這對(duì)于該點(diǎn)是獨(dú)特的。一組兩個(gè)或更多點(diǎn)形成一條直線(xiàn)將產(chǎn)生在該線(xiàn)的處交叉的正弦曲線(xiàn)。因此,檢測(cè)共線(xiàn)點(diǎn)的問(wèn)題可以轉(zhuǎn)化為找到并發(fā)曲線(xiàn)的問(wèn)題。
例子1
考慮下面三個(gè)點(diǎn),這里顯示為黑點(diǎn)
圖3
該圖顯示了Hough變換的第一步,三點(diǎn)和六個(gè)可能的角度分組。最左邊的圖像顯示正在轉(zhuǎn)換的第一個(gè)點(diǎn)。首先,繪制不同角度的線(xiàn)條,全部經(jīng)過(guò)第一點(diǎn)。這些顯示為實(shí)線(xiàn)。其次,對(duì)于每條實(shí)線(xiàn),找到也將原點(diǎn)平分的垂線(xiàn)(法線(xiàn),或者說(shuō)連接原點(diǎn)垂直于線(xiàn)段的線(xiàn)),這些顯示為虛線(xiàn)。然后找到虛線(xiàn)的長(zhǎng)度和角度。這些值顯示在圖表下方的表格中。這對(duì)被轉(zhuǎn)換的三個(gè)點(diǎn)中的每一個(gè)都重復(fù)該過(guò)程。然后將結(jié)果繪制成圖,有時(shí)稱(chēng)為霍夫空間圖。
圖4
這顯示一個(gè)霍夫空間圖,三點(diǎn)和六個(gè)可能的角度。這是前面表格中數(shù)據(jù)的一個(gè)簡(jiǎn)單圖表。線(xiàn)彼此交叉的點(diǎn)表示由作為變換輸入的三個(gè)點(diǎn)形成的線(xiàn)的角度和距離.
圖4顯示的曲線(xiàn)相交的點(diǎn)給出距離和角度。該距離和角度表示與被測(cè)試點(diǎn)相交的線(xiàn)。在圖4中,所示的線(xiàn)條在粉紅點(diǎn)相交; 這對(duì)應(yīng)于圖3中的實(shí)線(xiàn)粉紅線(xiàn),其穿過(guò)所有三個(gè)點(diǎn)。
在圖像分析上下文,邊緣段的點(diǎn)(一個(gè)或多個(gè))的坐標(biāo)在圖像中是已知的,并且因此作為參數(shù)線(xiàn)等式中的常量,而與是未知變量是我們要尋找的。如果我們繪制由每個(gè)定義的可能值,笛卡爾圖像空間中的點(diǎn)映射到極性霍夫參數(shù)空間中的曲線(xiàn)(即正弦曲線(xiàn))。這個(gè)點(diǎn)到曲線(xiàn)的變換是直線(xiàn)的霍夫變換。當(dāng)在霍夫參數(shù)空間中查看時(shí),在笛卡爾圖像空間中共線(xiàn)的點(diǎn)變得很明顯,因?yàn)樗鼈儺a(chǎn)生在相同點(diǎn)相交的曲線(xiàn)。
例子2
以下是顯示包含兩條粗線(xiàn)的光柵圖像上的霍夫變換結(jié)果的不同示例。
該變換的結(jié)果存儲(chǔ)在矩陣中。單元格值表示通過(guò)任意點(diǎn)的曲線(xiàn)數(shù)量。更高的單元格值變得更亮。兩個(gè)明顯的亮點(diǎn)是兩條線(xiàn)的霍夫參數(shù)。從這些點(diǎn)的位置,可以確定輸入圖像中兩條線(xiàn)的圖像中心的角度和距離。
霍夫變換提取直線(xiàn)如何實(shí)現(xiàn)?實(shí)現(xiàn)機(jī)理是為何???
通過(guò)將霍夫參數(shù)空間量化為有限間隔或累加器單元來(lái)實(shí)現(xiàn)變換。隨著算法的運(yùn)行,每個(gè)算法都把轉(zhuǎn)換為一個(gè)離散化的曲線(xiàn),并且沿著這條曲線(xiàn)的累加器單元被遞增。累加器陣列中產(chǎn)生的峰值表示圖像中存在相應(yīng)的直線(xiàn)的有力證據(jù)。??注意,現(xiàn)在我們考慮的是直線(xiàn)的霍夫變換(先不去考慮圓,圓的情況稍后簡(jiǎn)單說(shuō)明)。累加器陣列的維度是二維的(也就是r和)。
用霍夫變換檢測(cè)圓時(shí),累加器是三維累加器,目前不去論述
那么對(duì)于圖像來(lái)說(shuō),處的每個(gè)像素及其鄰域,霍夫變換算法被用于確定該像素是否有足夠的直線(xiàn)證據(jù)。如果是,它將計(jì)算該線(xiàn)的參數(shù),然后查找參數(shù)落入的累加器箱,并增加該箱的值(投票值)。通過(guò)查找具有最高值的箱,通常通過(guò)查找累加器空間中的局部最大值,可以提取最可能的線(xiàn),并且讀出它們的(近似的)幾何定義。
找到這些峰的最簡(jiǎn)單方法是通過(guò)應(yīng)用某種形式的閾值,但其他技術(shù)可能在不同情況下產(chǎn)生更好的結(jié)果 - 確定找到哪些行以及有多少。由于返回的行不包含任何長(zhǎng)度信息,因此通常有必要在下一步中查找圖像的哪些部分與哪些行匹配。此外,由于邊緣檢測(cè)步驟中存在缺陷誤差,通常會(huì)在累加器空間中出現(xiàn)錯(cuò)誤,這可能使得找到合適的峰值以及適當(dāng)?shù)木€(xiàn)條變得非常重要。
線(xiàn)性霍夫變換的最終結(jié)果是類(lèi)似于累加器的二維陣列(矩陣),該矩陣的一個(gè)維度是量化角度,另一個(gè)維度是量化距離r。矩陣的每個(gè)元素的值等于位于由量化參數(shù)表示的線(xiàn)上的點(diǎn)或像素的總和。所以具有最高值的元素表示輸入圖像中代表最多的直線(xiàn)。在某些論文中,可能把累計(jì)器單元的結(jié)果認(rèn)為是投票值。換句話(huà)說(shuō),將每個(gè)交點(diǎn)看成一次投票,也就是說(shuō),所有點(diǎn)都如此進(jìn)行計(jì)算后,可以設(shè)置一個(gè)閾值,投票大于這個(gè)閾值的可以認(rèn)為是找到的直線(xiàn)。下圖是從一個(gè)博客摘用。
分別為原圖,閾值為30,20時(shí)候檢測(cè)到的直線(xiàn)。對(duì)于大于閾值的點(diǎn),有其Hough space的參數(shù)對(duì)通過(guò)逆映射我們可以得到圖像空間中的直線(xiàn):
實(shí)現(xiàn)使用的例子說(shuō)明描述
霍夫變換可用于識(shí)別最適合一組給定邊緣點(diǎn)的曲線(xiàn)的參數(shù)。該邊緣描述通常從諸如Roberts Cross,Sobel或 Canny邊緣檢測(cè)器的特征檢測(cè)算子獲得,并且可能是嘈雜的,即其可能包含對(duì)應(yīng)于單個(gè)整體特征的多個(gè)邊緣片段。此外,由于邊緣檢測(cè)器的輸出僅限定圖像中的特征的位置,所以霍夫變換進(jìn)一步是確定兩個(gè)特征是什么(即檢測(cè)其具有參數(shù)(或其他)的特征描述)以及 它們有多少個(gè)存在于圖像中。
為了詳細(xì)說(shuō)明霍夫變換,我們從兩個(gè)閉合矩形的簡(jiǎn)單圖像開(kāi)始。
簡(jiǎn)單閉合矩形
使用 Canny邊緣檢測(cè)器可產(chǎn)生一組邊界描述的這個(gè)部分,如圖8所示。
這里我們看到了圖像中的整體邊界,但是這個(gè)結(jié)果并沒(méi)有告訴我們這個(gè)邊界描述中的特征的身份(和數(shù)量)。在這種情況下,我們可以使用Hough(線(xiàn)檢測(cè))變換來(lái)檢測(cè)該圖像的八個(gè)單獨(dú)的直線(xiàn)段,從而確定對(duì)象的真實(shí)幾何結(jié)構(gòu)。
如果我們使用這些邊緣/邊界點(diǎn)作為Hough變換的輸入,則會(huì)在笛卡爾空間中的每個(gè)邊緣點(diǎn)的極坐標(biāo)空間中生成一條曲線(xiàn)。當(dāng)被視為強(qiáng)度圖像時(shí),累加器陣列看起來(lái)像圖9所示
圖9
可以利用直方圖 均衡技術(shù)使得圖像可以讓我們看到包含在低強(qiáng)度像素值中的信息模式,如圖10所示。
注意,雖然和是概念上的極坐標(biāo),但是累加器空間以橫坐標(biāo)和縱坐標(biāo)的矩形繪制 。請(qǐng)注意,累加器空間環(huán)繞圖像的垂直邊緣,因此實(shí)際上只有8個(gè)實(shí)際峰值。
由梯度圖像中的共線(xiàn)點(diǎn)生成的曲線(xiàn)在霍夫變換空間中的峰中相交。這些交點(diǎn)表征原始圖像的直線(xiàn)段。有許多方法可用于從累加器陣列中提取這些亮點(diǎn)或局部最大值。例如,一個(gè)簡(jiǎn)單的方法涉及閾值處理,然后 對(duì)累加器陣列圖像中孤立的亮點(diǎn)集群進(jìn)行一些細(xì)化處理。這里我們使用相對(duì)閾值來(lái)提取,對(duì)應(yīng)于原始圖像中的每條直線(xiàn)邊緣的點(diǎn)。(換句話(huà)說(shuō),我們只采用累加器數(shù)組中的那些局部最大值,其值等于或大于全局最大值的某個(gè)固定百分比。)
從Hough變換空間(即,反霍夫變換)映射回笛卡爾空間產(chǎn)生一組圖像主題的線(xiàn)描述。通過(guò)將該圖像疊加在原始的反轉(zhuǎn)版本上,我們可以確認(rèn)霍夫變換找到兩個(gè)矩形的8個(gè)真實(shí)邊的結(jié)果,并且因此揭示了遮擋場(chǎng)景的基礎(chǔ)幾何形狀。
從Hough變換空間(即,反霍夫變換)映射回笛卡爾空間產(chǎn)生一組圖像主題的線(xiàn)描述。通過(guò)將該圖像疊加在原始的反轉(zhuǎn)版本上(見(jiàn)圖11),我們可以確認(rèn)霍夫變換找到兩個(gè)矩形的8個(gè)真實(shí)邊的結(jié)果,并且因此揭示了遮擋場(chǎng)景的基礎(chǔ)幾何形狀。
圖11
請(qǐng)注意,在這個(gè)簡(jiǎn)單的例子中,檢測(cè)到的和原始圖像線(xiàn)的對(duì)齊精度顯然不完美,這取決于累加器陣列的量化。(還要注意許多圖像邊緣有幾條檢測(cè)線(xiàn),這是因?yàn)橛袔讉€(gè)附近的霍夫空間峰值具有相似的線(xiàn)參數(shù)值,存在控制這種效應(yīng)的技術(shù),但這里沒(méi)有用來(lái)說(shuō)明標(biāo)準(zhǔn)霍夫變換。)
還要注意,由霍夫變換產(chǎn)生的線(xiàn)條的長(zhǎng)度是無(wú)限的。如果我們希望識(shí)別產(chǎn)生變換參數(shù)的實(shí)際線(xiàn)段,則需要進(jìn)一步的圖像分析以便查看這些無(wú)限長(zhǎng)線(xiàn)的哪些部分實(shí)際上具有點(diǎn)。
為了說(shuō)明Hough技術(shù)對(duì)噪聲的魯棒性,Canny邊緣描述已被破壞(由椒鹽噪聲引起), 在Hough變換之前,如圖12所示。
圖12
繪制在霍夫空間的結(jié)果如圖13所示。
圖13
將這個(gè)結(jié)果反霍夫變換(并將它覆蓋在原來(lái)的結(jié)果上,見(jiàn)圖14)
圖14
圖14:相對(duì)閾值設(shè)置為40%。
可以通過(guò)變換圖像來(lái)研究Hough變換對(duì)特征邊界中的間隙的敏感性(使用了畫(huà)圖工具進(jìn)行編輯,見(jiàn)圖15)
圖15
然后我們?cè)賹⑵渥儞Q到霍夫變換空間,表示為圖16所示。
圖16
然后使用40%的相對(duì)閾值去對(duì)圖像反霍夫變換(同樣也是疊加在原圖上
圖17
在這種情況下,因?yàn)槔奂悠骺臻g沒(méi)有接收到前面例子中的條目數(shù)量,只能找到7個(gè)峰值,但這些都是結(jié)構(gòu)相關(guān)的線(xiàn)。
前面的例子都不是自然實(shí)例。下面展示自然實(shí)例的例子。
城市場(chǎng)景
在第一種情況下,我們有一個(gè)城市場(chǎng)景,這些建筑物被霧遮住,見(jiàn)圖18。
圖18
如果我們想要找到建筑物的真實(shí)邊緣,邊緣檢測(cè)器(例如Canny)無(wú)法很好地恢復(fù)這些信息,如圖19所示。
圖19
但是,霍夫變換可以檢測(cè)到一些表示遮擋區(qū)域內(nèi)建筑物邊緣的直線(xiàn)。原始圖像的直方圖均衡累加器空間表示如圖20所示。
圖20
如果我們將相對(duì)閾值設(shè)置為70%,我們會(huì)得到如圖21所示的反霍夫變換圖像。
圖21
這里只能檢測(cè)到幾條長(zhǎng)邊,并且在很多線(xiàn)條或邊緣片段幾乎共線(xiàn)的地方存在很多重復(fù)。應(yīng)用更大的相對(duì)閾值(即50%)會(huì)產(chǎn)生如圖22所示效果。
圖22
會(huì)產(chǎn)生更多的預(yù)期線(xiàn)條,但會(huì)以許多共線(xiàn)邊緣碎片產(chǎn)生的許多虛假線(xiàn)條為代價(jià)。
最后一個(gè)例子來(lái)自遙感應(yīng)用。在這里,我們想要檢測(cè)圖像中的街道
遙感應(yīng)用
圖23
圖23顯示了一個(gè)合理的矩形城市扇區(qū)(rectangular city sector)。我們可以使用Canny邊緣檢測(cè)器來(lái)檢測(cè)該圖像,如圖24所示。
圖24
但是,街道信息不能單獨(dú)用作邊緣檢測(cè)器的輸出。
圖25表明霍夫線(xiàn)檢測(cè)器能夠恢復(fù)這些信息中的一些。但由于原始圖像的對(duì)比度較差,因此確定了一組有限的特征(即街道)。
圖25
實(shí)現(xiàn)算法描述
摘取一篇博客的算法描述:
初始化空間,表示在該參數(shù)表示的直線(xiàn)上的像素點(diǎn)的個(gè)數(shù))
對(duì)于每一個(gè)像素點(diǎn),在參數(shù)空間中找出滿(mǎn)足的對(duì),然后令
統(tǒng)計(jì)所有的大小,取出的參數(shù) (τ是預(yù)設(shè)的閾值)
但我覺(jué)得這并不是十分完整的算法流程。所以我將其改進(jìn)描述如下
讀取原始圖并轉(zhuǎn)換成灰度圖,采用邊緣檢測(cè)算子(如Canny)轉(zhuǎn)換成二值化邊緣圖像
然后對(duì)該圖像進(jìn)行霍夫變換
先使用峰值檢測(cè)函數(shù),找到大于閾值的霍夫變換單元(局部最大值應(yīng)該最可能是線(xiàn),步長(zhǎng)和量化會(huì)影響效果)
將上述識(shí)別出的一組候選峰,需要確定與其相關(guān)的線(xiàn)段及其起始點(diǎn)和終止點(diǎn)(這需要一定的算法,很多論文對(duì)此都做了改進(jìn),諸如蝴蝶形狀寬度,峰值走廊)
然后描繪于原圖(或結(jié)果圖)上
代碼實(shí)現(xiàn)
matlab版本
原圖
圖26
%讀取圖像
I = imread(‘huofu.jpg’);
% 轉(zhuǎn)換成灰度圖
grayI = rgb2gray(I);
% 創(chuàng)建二進(jìn)制圖像
BW = edge(grayI,‘canny’);
% 使用二值圖像創(chuàng)建Hough變換。
[H,T,R] = hough(BW);
imshow(H,[],‘XData’,T,‘YData’,R,。。。
‘InitialMagnification’,‘fit’);
xlabel(‘ heta’), ylabel(‘
ho’);
axis on, axis normal, hold on;
% 在圖像的霍夫變換中查找峰值
P = houghpeaks(H,5,‘threshold’,ceil(0.3*max(H(:))));
x = T(P(:,2)); y = R(P(:,1));
plot(x,y,‘s’,‘color’,‘white’);
% 找到線(xiàn)條并繪制它們
lines = houghlines(BW,T,R,P,‘FillGap’,5,‘MinLength’,7);
figure, imshow(I), hold on
max_len = 0;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),‘LineWidth’,2,‘Color’,‘green’);
% 繪制線(xiàn)條的開(kāi)始和結(jié)束
plot(xy(1,1),xy(1,2),‘x’,‘LineWidth’,2,‘Color’,‘yellow’);
plot(xy(2,1),xy(2,2),‘x’,‘LineWidth’,2,‘Color’,‘red’);
% 確定最長(zhǎng)線(xiàn)段的端點(diǎn)
len = norm(lines(k).point1 - lines(k).point2);
if ( len 》 max_len)
max_len = len;
xy_long = xy;
end
end
% 通過(guò)為青色著色來(lái)突出顯示最長(zhǎng)的線(xiàn)段
plot(xy_long(:,1),xy_long(:,2),‘LineWidth’,2,‘Color’,‘cyan’);
運(yùn)行結(jié)果
圖27
只是個(gè)示范使用,參數(shù)可自調(diào)。
python實(shí)現(xiàn)
#! python2
# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
from skimage.transform import hough_line
from skimage.draw import line
img = np.zeros((100, 150), dtype=bool)
img[30, :] = 1
img[:, 65] = 1
img[35:45, 35:50] = 1
rr, cc = line(60, 130, 80, 10)
img[rr, cc] = 1
img += np.random.random(img.shape) 》 0.95
out, angles, d = hough_line(img)
fix, axes = plt.subplots(1, 2, figsize=(7, 4))
axes[0].imshow(img, cmap=plt.cm.gray)
axes[0].set_title(‘Input image’)
axes[1].imshow(
out, cmap=plt.cm.bone,
extent=(np.rad2deg(angles[-1]), np.rad2deg(angles[0]), d[-1], d[0]))
axes[1].set_title(‘Hough transform’)
axes[1].set_xlabel(‘Angle (degree)’)
axes[1].set_ylabel(‘Distance (pixel)’)
plt.tight_layout()
plt.show()
運(yùn)行結(jié)果
圖28
Opencv實(shí)現(xiàn)
opencv的關(guān)于霍夫變換提取的函數(shù)可以在Opencv的該文檔見(jiàn)到 Opencv關(guān)于houghlines函數(shù) ??博主電腦安裝的是opencv2.4.13版本,代碼是來(lái)自于淺墨大神(毛星云)的代碼實(shí)現(xiàn)。
//-----------------------------------【頭文件包含部分】---------------------------------------
// 描述:包含程序所依賴(lài)的頭文件
//----------------------------------------------------------------------------------------------
#include 《opencv2/opencv.hpp》
#include 《opencv2/imgproc/imgproc.hpp》
//-----------------------------------【命名空間聲明部分】---------------------------------------
// 描述:包含程序所使用的命名空間
//-----------------------------------------------------------------------------------------------
using namespace cv;
//-----------------------------------【main( )函數(shù)】--------------------------------------------
// 描述:控制臺(tái)應(yīng)用程序的入口函數(shù),我們的程序從這里開(kāi)始
//-----------------------------------------------------------------------------------------------
int main()
{
//【1】載入原始圖和Mat變量定義
Mat srcImage = imread(“1.jpg”); //工程目錄下應(yīng)該有一張名為1.jpg的素材圖
Mat midImage, dstImage;//臨時(shí)變量和目標(biāo)圖的定義
//【2】進(jìn)行邊緣檢測(cè)和轉(zhuǎn)化為灰度圖
Canny(srcImage, midImage, 50, 200, 3);//進(jìn)行一此canny邊緣檢測(cè)
cvtColor(midImage, dstImage, CV_GRAY2BGR);//轉(zhuǎn)化邊緣檢測(cè)后的圖為灰度圖
//【3】進(jìn)行霍夫線(xiàn)變換
vector《Vec2f》 lines;//定義一個(gè)矢量結(jié)構(gòu)lines用于存放得到的線(xiàn)段矢量集合
HoughLines(midImage, lines, 1, CV_PI / 180, 150, 0, 0);
//【4】依次在圖中繪制出每條線(xiàn)段
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(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, CV_AA);
}
//【5】顯示原始圖
imshow(“【原始圖】”, srcImage);
//【6】邊緣檢測(cè)后的圖
imshow(“【邊緣檢測(cè)后的圖】”, midImage);
//【7】顯示效果圖
imshow(“【效果圖】”, dstImage);
waitKey(0);
return 0;
}
運(yùn)行結(jié)果
圖30
淺提霍夫變換提取圓
我們可以使用這個(gè)相同的程序來(lái)檢測(cè)具有分析描述的其他特征。例如,在圓圈的情況下,參數(shù)方程為
其中a和b是圓心的坐標(biāo)并且是半徑。在這種情況下,算法的計(jì)算復(fù)雜度開(kāi)始增加,因?yàn)槲覀儸F(xiàn)在在參數(shù)空間和三維累加器中有三個(gè)坐標(biāo)。(通常,累加器陣列的計(jì)算和大小隨著參數(shù)數(shù)量的增加而多項(xiàng)式增加,因此,基本霍夫技術(shù)僅適用于簡(jiǎn)單曲線(xiàn)。)
步驟
它的算法步驟如下:
首先創(chuàng)建累加器空間,由每個(gè)像素單元格構(gòu)成。最初每個(gè)單元格都設(shè)置為0。
然后對(duì)于每個(gè)圖像中的邊緣點(diǎn),按照?qǐng)A方程將那些可能是一個(gè)圓中心的單元格值進(jìn)行累加。這些單元格在等式中由字母a表示。
然后在前面的步驟中由每個(gè)可能找到的值a,區(qū)找到滿(mǎn)足等式的所有可能值b
搜索累加器空間中的局部最大值。這些單元格表示算法檢測(cè)到的圓圈。?? 如果我們不知道事先定位的圓的半徑,可以使用三維累加器空間來(lái)搜索具有任意半徑的圓。當(dāng)然,這在計(jì)算上更加昂貴。
該方法還可以檢測(cè)部分位于累加器空間外部的圓,只要該圓的區(qū)域內(nèi)仍有足夠的圓。
霍夫變換提取圓的一些實(shí)現(xiàn)鏈接
-matlab關(guān)于霍夫變換提取圓
Matlab圓提取(https://ww2.mathworks.cn/help/images/ref/imfindcircles.html)
-關(guān)于opencv的提取圓(給出了C++,C和Python)
Opencv官方文檔關(guān)于圓提取(https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=HoughCircles)
- python實(shí)現(xiàn)提取圓
Python圓提取(https://scikit-image.org/docs/dev/api/skimage.transform.html)
淺提廣義霍夫變換
當(dāng)我們希望隔離的特征的形狀不具有描述其邊界的簡(jiǎn)單解析方程時(shí),使用廣義Hough變換。在這種情況下,我們不使用曲線(xiàn)的參數(shù)方程,而是使用查找表來(lái)定義邊界位置和方向與霍夫參數(shù)之間的關(guān)系。(必須使用原型形狀在初步階段計(jì)算查找表值。)
例如,假設(shè)我們知道所需特征的形狀和方向。(見(jiàn)下圖)我們可以在特征中指定一個(gè)任意參考點(diǎn),其中定義了特征的形狀(即r從邊界到這個(gè)參考點(diǎn)的法線(xiàn)的距離和角度ω。我們的查找表(即 R表)將由這些距離和方向?qū)M成,由邊界的方向ω索引
圖31
圖31:R表組件的描述。
霍夫變換空間現(xiàn)在是根據(jù)圖像中形狀的可能位置來(lái)定義的,即可能的范圍。換句話(huà)說(shuō),轉(zhuǎn)換定義為:
(對(duì)于特定的已知方向,β值和來(lái)自于表值)。如果所需特征的方向未知,則該過(guò)程變得復(fù)雜,因?yàn)槲覀儽仨毻ㄟ^(guò)引入額外參數(shù)來(lái)擴(kuò)展累加器,以考慮方向。
基本霍夫變換的限制
霍夫變換只有在大量投票落入正確的分箱時(shí)才有效,因此可以在背景噪音中輕松檢測(cè)分箱。這意味著垃圾箱不能太小,否則有些選票會(huì)落入鄰近垃圾箱,從而降低主垃圾箱的可見(jiàn)度。
另外,當(dāng)參數(shù)數(shù)量很大時(shí)(也就是說(shuō),當(dāng)我們使用通常超過(guò)三個(gè)參數(shù)的霍夫變換時(shí)),單個(gè)分箱中投的平均投票數(shù)非常低,而這些分箱對(duì)應(yīng)的實(shí)際數(shù)字在圖像中的投票數(shù)量并不一定比其鄰居多得多。復(fù)雜性以一定的速率增加,其中每個(gè)附加參數(shù)是圖像空間的大小和m是參數(shù)的數(shù)量。因此,必須非常小心地使用Hough變換來(lái)檢測(cè)線(xiàn)條或圓圈以外的任何其他內(nèi)容。
最后,霍夫變換的大部分效率取決于輸入數(shù)據(jù)的質(zhì)量:為了使霍夫變換高效,必須檢測(cè)邊緣。在噪聲圖像上使用Hough變換是一個(gè)非常棘手的問(wèn)題,一般而言,之前必須使用降噪階段。在圖像被斑點(diǎn)破壞的情況下(如雷達(dá)圖像中的情況),Radon變換有時(shí)更適合檢測(cè)線(xiàn),因?yàn)樗ㄟ^(guò)求和來(lái)衰減噪聲。
結(jié)語(yǔ)
本博文主要描述基本經(jīng)典的霍夫變換,描述了霍夫變換如何提取直線(xiàn)及其原理,展示了部分例子和代碼實(shí)現(xiàn),也擴(kuò)展了一部分霍夫變換的簡(jiǎn)單描述,希望能對(duì)看者有所借鑒。
編輯:jq
-
光柵
+關(guān)注
關(guān)注
0文章
287瀏覽量
27526 -
邊緣檢測(cè)
+關(guān)注
關(guān)注
0文章
92瀏覽量
18216 -
累加器
+關(guān)注
關(guān)注
0文章
50瀏覽量
9462
原文標(biāo)題:一文解讀經(jīng)典霍夫變換(Hough Transform)
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺(jué)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論