當前位置:首頁 » 編程語言 » 分水嶺演算法python

分水嶺演算法python

發布時間: 2024-05-28 14:56:25

㈠ 圖像分割

圖像閾值化分割是一種傳統的最常用的圖像分割方法,因其實現簡單、計算量小、性能較穩定而成為圖像分割中最基本和應用最廣泛的分割技術。它特別適用於目標和背景占據不同灰度級范圍的圖像。它不僅可以極大的壓縮數據量,而且也大大簡化了分析和處理步驟,因此在很多情況下,是進行圖像分析、特徵提取與模式識別之前的必要的圖像預處理過程。

圖像閾值化的目的是要按照灰度級,對像素集合進行一個劃分,得到的每個子集形成一個與現實景物相對應的區域,各個區域內部具有一致的屬性,而相鄰區域不具有這種一致屬性。這樣的劃分可以通過從灰度級出發選取一個或多個閾值來實現。

基本原理是:通過設定不同的特徵閾值,把圖像象素點分為若干類。
常用的特徵包括:直接來自原始圖像的灰度或彩色特徵;由原始灰度或彩色值變換得到的特徵。
設原始圖像為f(x,y),按照一定的准則f(x,y)中找到特徵值T,將圖像分割為兩個部分,分割後的圖像為:
若取:b0=0(黑),b1=1(白),即為我們通常所說的圖像二值化。

閾值分割方法實際上是輸入圖像f到輸出圖像g的如下變換:

其中,T為閾值,對於物體的圖像元素g(i,j)=1,對於背景的圖像元素g(i,j)=0。

由此可見,閾值分割演算法的關鍵是確定閾值,如果能確定一個合適的閾值就可准確地將圖像分割開來。閾值確定後,將閾值與像素點的灰度值逐個進行比較,而且像素分割可對各像素並行地進行,分割的結果直接給出圖像區域。
閾值分割的優點是計算簡單、運算效率較高、速度快。有著各種各樣的閾值處理技術,包括全局閾值、自適應閾值、最佳閾值等等。

閾值處理技術參看:

區域分割是講圖像按照相似性准則分成不同的區域,主要包括區域增長,區域分裂合並和分水嶺等幾種類型。

區域生長是一種串列區域分割的圖像分割方法。區域生長是指從某個像素出發,按照一定的准則,逐步加入鄰近像素,當滿足一定的條件時,區域生長終止。區域生長的好壞決定於1. 初始點(種子點)的選取。 2. 生長准則。 3. 終止條件 。區域生長是從某個或者某些像素點出發,最後得到整個區域,進而實現目標的提取。

區域生長的基本思想是將具有相似性質的像素集合起來構成區域。具體先對每個需要分割的區域找一個種子像素作為生長的起點,然後將種子像素周圍鄰域中與種子像素有相同或相似性質的像素(根據某種事先確定的生長或相似准則來判定)合並到種子像素所在的區域中。將這些新像素當作新的種子像素繼續進行上面的過程,直到再沒有滿足條件的像素可被包括進來。這樣一個區域就長成了。

區域生長需要選擇一組能正確代表所需區域的種子像素,確定在生長過程中的相似性准則,制定讓生長停止的條件或准則。相似性准則可以是灰度級、彩色、紋理、梯度等特性。選取的種子像素可以是單個像素,也可以是包含若干個像素的小區域。大部分區域生長准則使用圖像的局部性質。生長准則可根據不同原則制定,而使用不同的生長准則會影響區域生長的過程。

圖1是區域增長的示例。

區域生長是一種古老的圖像分割方法,最早的區域生長圖像分割方法是由Levine等人提出的。該方法一般有兩種方式,一種是先給定圖像中要分割的目標物體內的一個小塊或者說種子區域(seed point),再在種子區域基礎上不斷將其周圍的像素點以一定的規則加入其中,達到最終將代表該物體的所有像素點結合成一個區域的目的;另一種是先將圖像分割成很多的一致性較強,如區域內像素灰度值相同的小區域,再按一定的規則將小區域融合成大區域,達到分割圖像的目的,典型的區域生長法如T. C. Pong等人提出的基於小面(facet)模型的區域生長法,區域生長法固有的缺點是往往會造成過度分割,即將圖像分割成過多的區域

區域生長實現的步驟如下:

區域分裂合並演算法的基本思想是先確定一個分裂合並的准則,即區域特徵一致性的測度,當圖像中某個區域的特徵不一致時就將該區域分裂成4個相等的子區域,當相鄰的子區域滿足一致性特徵時則將它們合成一個大區域,直至所有區域不再滿足分裂合並的條件為止。當分裂到不能再分的情況時,分裂結束,然後它將查找相鄰區域有沒有相似的特徵,如果有就將相似區域進行合並,最後達到分割的作用。在一定程度上區域生長和區域分裂合並演算法有異曲同工之妙,互相促進相輔相成的,區域分裂到極致就是分割成單一像素點,然後按照一定的測量准則進行合並,在一定程度上可以認為是單一像素點的區域生長方法。區域生長比區域分裂合並的方法節省了分裂的過程,而區域分裂合並的方法可以在較大的一個相似區域基礎上再進行相似合並,而區域生長只能從單一像素點出發進行生長(合並)。

反復進行拆分和聚合以滿足限制條件的演算法。

令R表示整幅圖像區域並選擇一個謂詞P。對R進行分割的一種方法是反復將分割得到的結果圖像再次分為四個區域,直到對任何區域Ri,有P(Ri)=TRUE。這里是從整幅圖像開始。如果P(R)=FALSE,就將圖像分割為4個區域。對任何區域如果P的值是FALSE.就將這4個區域的每個區域再次分別分為4個區域,如此不斷繼續下去。這種特殊的分割技術用所謂的四叉樹形式表示最為方便(就是說,每個非葉子節點正好有4個子樹),這正如圖10.42中說明的樹那樣。注意,樹的根對應於整幅圖像,每個節點對應於劃分的子部分。此時,只有R4進行了進一步的再細分。

如果只使用拆分,最後的分區可能會包含具有相同性質的相鄰區域。這種缺陷可以通過進行拆分的同時也允許進行區域聚合來得到矯正。就是說,只有在P(Rj∪Rk)=TRUE時,兩個相鄰的區域Rj和Rk才能聚合。
前面的討論可以總結為如下過程。在反復操作的每一步,我們需要做:

可以對前面講述的基本思想進行幾種變化。例如,一種可能的變化是開始時將圖像拆分為一組圖象塊。然後對每個塊進一步進行上述拆分,但聚合操作開始時受只能將4個塊並為一組的限制。這4個塊是四叉樹表示法中節點的後代且都滿足謂詞P。當不能再進行此類聚合時,這個過程終止於滿足步驟2的最後的區域聚合。在這種情況下,聚合的區域可能會大小不同。這種方法的主要優點是對於拆分和聚合都使用同樣的四叉樹,直到聚合的最後一步。

分水嶺分割方法,是一種基於拓撲理論的數學形態學的分割方法,其基本思想是把圖像看作是測地學上的拓撲地貌,圖像中每一點像素的灰度值表示該點的海拔高度,每一個局部極小值及其影響區域稱為集水盆,而集水盆的邊界則形成分水嶺。分水嶺的概念和形成可以通過模擬浸入過程來說明。在每一個局部極小值表面,刺穿一個小孔,然後把整個模型慢慢浸入水中,隨著浸入的加深,每一個局部極小值的影響域慢慢向外擴展,在兩個集水盆匯合處構築大壩,即形成分水嶺。

分水嶺的計算過程是一個迭代標注過程。分水嶺比較經典的計算方法是L. Vincent提出的。在該演算法中,分水嶺計算分兩個步驟,一個是排序過程,一個是淹沒過程。首先對每個像素的灰度級進行從低到高排序,然後在從低到高實現淹沒過程中,對每一個局部極小值在h階高度的影響域採用先進先出(FIFO)結構進行判斷及標注。

分水嶺變換得到的是輸入圖像的集水盆圖像,集水盆之間的邊界點,即為分水嶺。顯然,分水嶺表示的是輸入圖像極大值點。因此,為得到圖像的邊緣信息,通常把梯度圖像作為輸入圖像,即

分水嶺演算法對微弱邊緣具有良好的響應,圖像中的雜訊、物體表面細微的灰度變化,都會產生過度分割的現象。但同時應當看出,分水嶺演算法對微弱邊緣具有良好的響應,是得到封閉連續邊緣的保證的。另外,分水嶺演算法所得到的封閉的集水盆,為分析圖像的區域特徵提供了可能。
為消除分水嶺演算法產生的過度分割,通常可以採用兩種處理方法,一是利用先驗知識去除無關邊緣信息。二是修改梯度函數使得集水盆只響應想要探測的目標。

為降低分水嶺演算法產生的過度分割,通常要對梯度函數進行修改,一個簡單的方法是對梯度圖像進行閾值處理,以消除灰度的微小變化產生的過度分割。即

程序可採用方法:用閾值限制梯度圖像以達到消除灰度值的微小變化產生的過度分割,獲得適量的區域,再對這些區域的邊緣點的灰度級進行從低到高排序,然後在從低到高實現淹沒的過程,梯度圖像用Sobel運算元計算獲得。對梯度圖像進行閾值處理時,選取合適的閾值對最終分割的圖像有很大影響,因此閾值的選取是圖像分割效果好壞的一個關鍵。缺點:實際圖像中可能含有微弱的邊緣,灰度變化的數值差別不是特別明顯,選取閾值過大可能會消去這些微弱邊緣。

參考文章:

圖像分割的一種重要途徑是通過邊緣檢測,即檢測灰度級或者結構具有突變的地方,表明一個區域的終結,也是另一個區域開始的地方。這種不連續性稱為邊緣。不同的圖像灰度不同,邊界處一般有明顯的邊緣,利用此特徵可以分割圖像。

圖像中邊緣處像素的灰度值不連續,這種不連續性可通過求導數來檢測到。對於階躍狀邊緣,其位置對應一階導數的極值點,對應二階導數的過零點(零交叉點)。因此常用微分運算元進行邊緣檢測。常用的一階微分運算元有Roberts運算元、Prewitt運算元和Sobel運算元,二階微分運算元有Laplace運算元和Kirsh運算元等。在實際中各種微分運算元常用小區域模板來表示,微分運算是利用模板和圖像卷積來實現。這些運算元對雜訊敏感,只適合於雜訊較小不太復雜的圖像。

由於邊緣和雜訊都是灰度不連續點,在頻域均為高頻分量,直接採用微分運算難以克服雜訊的影響。因此用微分運算元檢測邊緣前要對圖像進行平滑濾波。LoG運算元和Canny運算元是具有平滑功能的二階和一階微分運算元,邊緣檢測效果較好,

在邊緣檢測演算法中,前三個步驟用得十分普遍。這是因為大多數場合下,僅僅需要邊緣檢測器指出邊緣出現在圖像某一像素點的附近,而沒有必要指出邊緣的精確位置或方向.邊緣檢測誤差通常是指邊緣誤分類誤差,即把假邊緣判別成邊緣而保留,而把真邊緣判別成假邊緣而去掉.邊緣估計誤差是用概率統計模型來描述邊緣的位置和方向誤差的.我們將邊緣檢測誤差和邊緣估計誤差區分開,是因為它們的計算方法完全不同,其誤差模型也完全不同.

Roberts運算元 :邊緣定位準,但是對雜訊敏感。適用於邊緣明顯且雜訊較少的圖像分割。Roberts邊緣檢測運算元是一種利用局部差分運算元尋找邊緣的運算元,Robert運算元圖像處理後結果邊緣不是很平滑。經分析,由於Robert運算元通常會在圖像邊緣附近的區域內產生較寬的響應,故採用上述運算元檢測的邊緣圖像常需做細化處理,邊緣定位的精度不是很高。

Prewitt運算元 :對雜訊有抑製作用,抑制雜訊的原理是通過像素平均,但是像素平均相當於對圖像的低通濾波,所以Prewitt運算元對邊緣的定位不如Roberts運算元。

Sobel運算元 :Sobel運算元和Prewitt運算元都是加權平均,但是Sobel運算元認為,鄰域的像素對當前像素產生的影響不是等價的,所以距離不同的像素具有不同的權值,對運算元結果產生的影響也不同。一般來說,距離越遠,產生的影響越小。

Isotropic Sobel運算元 :加權平均運算元,權值反比於鄰點與中心點的距離,當沿不同方向檢測邊緣時梯度幅度一致,就是通常所說的各向同性。
在邊沿檢測中,常用的一種模板是Sobel 運算元。Sobel 運算元有兩個,一個是檢測水平邊沿的;另一個是檢測垂直平邊沿的 。Sobel運算元另一種形式是各向同性Sobel(Isotropic Sobel)運算元,也有兩個,一個是檢測水平邊沿的,另一個是檢測垂直平邊沿的 。各向同性Sobel運算元和普通Sobel運算元相比,它的位置加權系數更為准確,在檢測不同方向的邊沿時梯度的幅度一致。由於建築物圖像的特殊性,我們可以發現,處理該類型圖像輪廓時,並不需要對梯度方向進行運算,所以程序並沒有給出各向同性Sobel運算元的處理方法。

1971年,R.Kirsch[34]提出了一種能檢測邊緣方向的Kirsch運算元新方法:它使用了8個模板來確定梯度幅度值和梯度的方向。

圖像中的每個點都用8個掩模進行卷積,每個掩模對某個特定邊緣方向作出最大響應。所有8個方向中的最大值作為邊緣幅度圖像的輸出。最大響應掩模的序號構成了對邊緣方向的編碼。
Kirsch運算元的梯度幅度值用如下公式:

不同檢測運算元的對比:

參考文章:

文章引用於 木夜溯
編輯 Lornatang
校準 Lornatang

㈡ 圖像分割演算法總結

       圖像處理的很多任務都離不開圖像分割。因為圖像分割在cv中實在太重要(有用)了,就先把圖像分割的常用演算法做個總結。

        接觸機器學習和深度學習時間已經不短了。期間看過各種相關知識但從未總結過。本文過後我會盡可能詳細的從工程角度來總結,從傳統機器學習演算法,傳統計算機視覺庫演算法到深度學習目前常用演算法和論文,以及模型在各平台的轉化,量化,服務化部署等相關知識總結。

        圖像分割常用演算法大致分為下面幾類。由於圖像的能量范函,邊緣追蹤等方法的效果往往只能解決特定問題,效果並不理想,這里不再闡述。當然二值化本身也可以分割一些簡單圖像的。但是二值化演算法較多,我會專門做一個文章來總結。這里不再贅述。

        1.基於邊緣的圖像分割演算法:

            有利用圖像梯度的傳統演算法運算元的sobel,roberts,prewitt,拉普拉斯以及canny等。

            這些演算法的基本思想都是採用合適的卷積運算元,對圖像做卷積。從而求出圖像對應的梯度圖像。(至於為什麼通過如圖1這樣的運算元卷積,即可得到圖像的梯度圖像,請讀者復習下卷積和倒數的概念自行推導)由於圖像的邊緣處往往是圖像像素差異較大,梯度較大地方。因此我們通過合適的卷積核得到圖像的梯度圖像,即得到了圖像的邊緣圖像。至於二階運算元的推導,與一階類似。優點:傳統運算元梯度檢測,只需要用合適的卷積核做卷積,即可快速得出對應的邊緣圖像。缺點:圖像邊緣不一定準確,復雜圖像的梯度不僅僅出現在圖像邊緣,可以能出現在圖像內部的色彩和紋理上。

             也有基於深度學習方法hed,rcf等。由於這類網路都有同一個比較嚴重的缺陷,這里只舉例hed網路。hed是基於FCN和VGG改進,同時引出6個loss進行優化訓練,通過多個層輸出不同scale的粒度的邊緣,然後通過一個訓練權重融合各個層的邊緣結果。hed網路結構如下:

可以得到一個比較完整的梯度圖像,可參考github的hed實現。優點:圖像的梯度細節和邊緣完整性,相比傳統的邊緣運算元要好很多。但是hed對於邊緣的圖像內部的邊緣並不能很好的區分。當然我們可以自行更改loss來嘗試只擬合外部的圖像邊緣。但最致命的問題在於,基於vgg的hed的網路表達能力有限,對於圖像和背景接近,或者圖像和背景部分相融的圖片,hed似乎就有點無能為力了。

        2.基於區域分割的演算法:

            區域分割比較常用的如傳統的演算法結合遺傳演算法,區域生長演算法,區域分裂合並,分水嶺演算法等。這里傳統演算法的思路是比較簡單易懂的,如果有無法理解的地方,歡迎大家一起討論學習。這里不再做過多的分析。

            基於區域和語意的深度學習分割演算法,是目前圖像分割成果較多和研究的主要方向。例如FCN系列的全卷積網路,以及經典的醫學圖像分割常用的unet系列,以及rcnn系列發展下的maskrcnn,以及18年底的PAnet。基於語意的圖像分割技術,無疑會成為圖像分割技術的主流。

            其中,基於深度學習語意的其他相關演算法也可以間接或直接的應用到圖像分割。如經典的圖像matting問題。18年又出現了許多非常優秀的演算法和論文。如Deep-Image-Matting,以及效果非常優秀的MIT的 semantic soft segmentation(sss).

            基於語意的圖像分割效果明顯要好於其他的傳統演算法。我在解決圖像分割的問題時,首先嘗試用了hed網路。最後的效果並不理想。雖然也參考github,做了hed的一些fine-tune,但是還是上面提到的原因,在我多次嘗試後,最終放棄。轉而適用FCN系列的網路。但是fcn也無法解決圖像和背景相融的問題。圖片相融的分割,感覺即需要大的感受野,又需要未相融部分原圖像細節,所以單原FCN的網路,很難做出准確的分割。中間還測試過很多其他相關的網路,但都效果不佳。考慮到感受野和原圖像細節,嘗試了resnet和densenet作為圖像特徵提取的底層。最終我測試了unet系列的網路:

                unet的原始模型如圖所示。在自己拍照爬蟲等手段採集了將近1000張圖片。去掉了圖片質量太差的,圖片內容太過類似的。爬蟲最終收集160多張,自己拍照收集200張圖片後,又用ps手動p了邊緣圖像,採用圖像增強變換,大約有300*24張圖片。原生unet網路的表現比較一般。在將unet普通的卷積層改為resnet後,網路的表達能力明顯提升。在將resnet改為resnet101,此時,即使對於部分相融的圖像,也能較好的分割了。但是unet的模型體積已經不能接受。

                在最後階段,看到maskrcnn的實例分割。maskrcnn一路由rcnn,fasterrcnn發展過來。於是用maskrcnn來加入自己的訓練數據和label圖像進行訓練。maskrcnn的結果表現並不令人滿意,對於邊緣的定位,相比於其他演算法,略顯粗糙。在產品應用中,明顯還不合適。                

        3.基於圖的分割演算法

            基於深度學習的deepgrab,效果表現並不是十分理想。deepgrab的git作者backbone採用了deeplabv2的網路結構。並沒有完全安裝原論文來做。

論文原地址參考: https://arxiv.org/pdf/1707.00243.pdf

整體結構類似於encode和decoder。並沒有太仔細的研究,因為基於resent101的結構,在模型體積,速度以及deeplab的分割精度上,都不能滿足當前的需求。之前大致總結過計算機視覺的相關知識點,既然目前在討論移動端模型,那後面就分模塊總結下移動端模型的應用落地吧。

由於時間實在有限。這里並沒有針對每個演算法進行詳細的講解。後續我會從基礎的機器學習演算法開始總結。

㈢ 幫幫我 我不知道分水嶺演算法在圖像分割中的應用…… 代碼,還有別的幫幫我

clear,clc

%三種方法進行分水嶺分割
%讀入圖像
filename='sar1.bmp';
f=imread(filename);
Info=imfinfo(filename);
if Info.BitDepth>8
f=rgb2gray(f);
end
figure,mesh(double(f));%顯示圖像,類似集水盆地

%方法1:一般分水嶺分割,從結果可以看出存在過分割問題
b=im2bw(f,graythresh(f));%二值化,注意應保證集水盆地的值較低(為0),否則就要對b取反
d=bwdist(b); %求零值到最近非零值的距離,即集水盆地到分水嶺的距離
l=watershed(-d); %matlab自帶分水嶺演算法,l中的零值即為風水嶺
w=l==0; %取出邊緣
g=b&~w; %用w作為mask從二值圖像中取值
figure
subplot(2,3,1),imshow(f);
subplot(2,3,2),imshow(b);
subplot(2,3,3),imshow(d);
subplot(2,3,4),imshow(l);
subplot(2,3,5),imshow(w);
subplot(2,3,6),imshow(g);

%方法2:使用梯度的兩次分水嶺分割,從結果可以看出還存在過分割問題(在方法1的基礎上改進)
h=fspecial('sobel');%獲得縱方向的sobel運算元
fd=double(f);
g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2);%使用sobel運算元進行梯度運算
l=watershed(g);%分水嶺運算
wr=l==0;

g2=imclose(imopen(g,ones(3,3)),ones(3,3));%進行開閉運算對圖像進行平滑
l2=watershed(g2);%再次進行分水嶺運算
wr2=l2==0;
f2=f;
f2(wr2)=255;

figure
subplot(2,3,1),imshow(f);
subplot(2,3,2),imshow(g);
subplot(2,3,3),imshow(l);
subplot(2,3,4),imshow(g2);
subplot(2,3,5),imshow(l2);
subplot(2,3,6),imshow(f2);

%方法3:使用梯度加掩模的三次分水嶺演算法(在方法2的基礎上改進)
h=fspecial('sobel');%獲得縱方向的sobel運算元
fd=double(f);
g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2);%使用sobel運算元進行梯度運算
l=watershed(g);%分水嶺運算
wr=l==0;

rm=imregionalmin(g); %計算圖像的區域最小值定位,該函數僅僅是用來觀察為何分水嶺演算法產生這么多集水盆地
im=imextendedmin(f,2);%上面僅是產生最小值點,而該函數則是得到最小值附近的區域,此處的附近是相差2的區域
fim=f;
fim(im)=175; %將im在原圖上標識出,用以觀察
lim=watershed(bwdist(im));%再次分水嶺計算
em=lim==0;
g2=imimposemin(g,im|em);%在梯度圖上標出im和em,im是集水盆地的中心,em是分水嶺
l2=watershed(g2); %第三次分水嶺計算
f2=f;
f2(l2==0)=255; %從原圖對分水嶺進行觀察
figure
subplot(3,3,1),imshow(f);
subplot(3,3,2),imshow(g);
subplot(3,3,3),imshow(l);
subplot(3,3,4),imshow(im);
subplot(3,3,5),imshow(fim);
subplot(3,3,6),imshow(lim);
subplot(3,3,7),imshow(g2);
subplot(3,3,8),imshow(l2)
subplot(3,3,9),imshow(f2);

㈣ 分水嶺演算法的原理及相關思想的闡述是什麼

首先選擇最低的點,就是分水嶺中最底的山谷。
然後灌水:
1 . 極值點周圍的點也劃分到極值點,它們屬於一個區域。
2 . 在灌水的過程中根據你設定的閾值,還需要把有的區域合並。
3. 這個過程中有新的局部極值點產生,也是山谷,但不一定是最底的山谷。
最後灌滿了水之後,由起始的極值點形成了一個一個的區域。

熱點內容
crm客戶管理系統源碼 發布:2024-11-27 07:59:26 瀏覽:363
匠辰app安卓在哪裡下載 發布:2024-11-27 07:47:12 瀏覽:731
sql表操作 發布:2024-11-27 07:46:31 瀏覽:813
雲頂之腳本 發布:2024-11-27 07:45:37 瀏覽:658
編程箴言pdf 發布:2024-11-27 07:43:59 瀏覽:369
傳奇腳本經驗卷 發布:2024-11-27 07:43:16 瀏覽:679
我的世界手機版國際服怎麼創建自己的伺服器 發布:2024-11-27 07:38:19 瀏覽:693
java中立方 發布:2024-11-27 07:07:05 瀏覽:484
編程Q1 發布:2024-11-27 06:52:29 瀏覽:459
版本編譯驗證 發布:2024-11-27 06:46:43 瀏覽:938