骨架提取 Khalid Sheed的K3M演算法

2021-06-21 18:04:18 字數 3271 閱讀 5394

影象的骨架似乎沒有嚴格的數學定義,可認為是影象細化(thinning)的產物(中軸可以看作一種骨架,其有嚴格的數學定義)。目前已經有許多細化演算法,這些演算法得到的骨架可能略有差異。本文實現了khalid sheed 的 k3m演算法。該演算法屬於迭代腐蝕邊界的一類演算法,該類演算法的思想是,假定從二值影象中物體的邊界處同時開始燃燒,物體就會被逐步細化,但在燃燒過程中要保證滿足一定條件的點被保留或者被「燒掉」,以確定燃燒結束後,剩下的最後一畫素寬的影象為影象的骨架。這些條件的確定沒有統一的標準,各個演算法採取了不同的方案。一般來講,為了滿足計算的速度要求和演算法的準確,迭代中演算法會對影象邊界上某點的3*3鄰域內進行檢查,判斷是否滿足要求。

k3m演算法在每次迭代中需要進行六次檢查

phase 0. 標記出影象的邊界,

phase 1. 如果該點的鄰域中有3個點(非零,以下皆如此)相鄰,刪除該點

phase 2. 如果該點的鄰域中有3或4個點相鄰,刪除該點。

phase 3. 如果該點的鄰域中有3,4,5個點相鄰,刪除該點。

phase 4. 如果該點的鄰域中有3,4,5,6個點相鄰,刪除該點。

phase 5. 如果該點的鄰域中有3,4,5,6,7個點相鄰,刪除該點。

phase 6. 剩餘的邊界點取消標記,如果phase 5中沒有點被修改,停止迭代,否則返回phase 0。

具體的步驟可以閱讀**:**中演算法實現的乙個小技巧是,對鄰域中的8個點的值看作二進位制,即二進位制編碼,這樣不同的值就對應鄰域中不同的狀態。迭代中通過計算即可判斷該點是否滿足條件,是否可以刪除。具體細節請移步閱讀**。

演算法的測試結果如下:

參考:[cpp]view plain

copy

#include 

#include 

#include 

#include

#include

#include

using

std::vector;  

vector

> getflags(

inta,

intlength)  

;  for

(int

i=0;i

}  std::cout

vec;  

}  void

skeleton(cv::mat &input) 

//input-binary image

;  int

a1=;  

inta2=;  

inta3=;  

inta4=;  

inta5=;  

vector

> a0=getflags(a0,6);  

vector

> a1=getflags(a1,1);  

vector

> a2=getflags(a2,2);  

vector

> a3=getflags(a3,3);  

vector

> a4=getflags(a4,4);  

vector

> a5=getflags(a5,5);  

vectorborder;  

bool

modify=

true

;  int

neighbour[3][3]=,  

,    

};  

introw=input.rows;  

intcol=input.cols;  

while

(modify)  

}  if(std::find(a0.begin(),a0.end(),weight)!=a0.end())  

border.push_back(cv::point2i(m,n));  

}  }  

//pharse 1

vector::iterator first=border.begin();  

while

(first!=border.end())  

}  if(std::find(a1.begin(),a1.end(),weight)!=a1.end())  

else

++first;  

}  //pharse2

first=border.begin();  

while

(first!=border.end())  

}  if(std::find(a2.begin(),a2.end(),weight)!=a2.end())  

else

++first;  

}  //pharse3

first=border.begin();  

while

(first!=border.end())  

}  if(std::find(a3.begin(),a3.end(),weight)!=a3.end())  

else

++first;  

}  //pharse4

first=border.begin();  

while

(first!=border.end())  

}  if(std::find(a4.begin(),a4.end(),weight)!=a4.end())  

else

++first;  

}  //pharse5

first=border.begin();  

while

(first!=border.end())  

}  if(std::find(a5.begin(),a5.end(),weight)!=a5.end())  

else

++first;  

}  //pharse6

border.clear();  

}  for

(int

m=1;m

}  if(std::find(a0.begin(),a0.end(),weight)!=a0.end())  

input.at(m,n)=0;;  

}  }  

}  int

main()  

}  cv::imshow("output"

,binaryimage);  

cv::waitkey(0);  

return

0;  

}  

提取骨架 細化

bool iscontourp int x,int y,iplimage src img int linebytes src img widthstep byte lpptr byte src img imagedata linebytes y x p 2 lpptr linebytes true ...

骨架提取演算法應用

1 引言 根據個人理解,骨架提取 顧名思義 就是根據各個連通區域,將其抽離出與其輪廓近似的單畫素表示形態。以便於直觀觀察 影象的後繼處理。因此可以將其視為影象處理中的預處理,其操作是基於二值圖。為了更好的提取影象骨架,必要時需要對影象進行相應的預處理 比如去噪 濾波 形態學變換等 我的應用主要集中在...

視覺組學習內容 Zhang Suen骨架提取演算法

封裝 這是視覺組dalao給大家布置的學期末學習任務。因為之前沒有接觸過linux,環境也沒有配置好,對很多操作不夠熟悉,做這個任務從頭到尾大約花了兩天合計15個小時的時間,中間還問過dalao兩個小時左右的問題 此處給大佬比心 雖然和大佬說的三個小時相去甚遠但是最後還是趕在ddl之前完成了任務。總...