原文做者:aircrafthtml
原文地址:https://www.cnblogs.com/DOMLX/p/8672489.html前端
文中的一些圖片以及思想不少都是參考https://www.cnblogs.com/My-code-z/p/5712524.html 大佬的思想 以及本身作一些我的理解的補充python
若想下載指靜脈識別入門代碼:https://github.com/lmskyle/processc++
細化算法原理理解起來並不難,藉助矩陣九宮格來實現。將九宮格定義而且編號成以下格式。git
在講解以前有必要先看看書中是怎麼說的:github
書中說的仍是比較簡潔的,畢竟是大牛寫的,他們以爲很簡單容易理解的東西,咱們看起來就未必是這樣了。好了閒話很少說 進入主題。算法
第一步:爲了避免影響原圖像的一些其餘操做,先將原圖像拷貝一份用來細化處理,在將細化後圖片返回出去。編程
第二步:就跟書裏看的那樣,須要知足四個條件來才能進行刪除該點像素。這裏進行的是沿着東南邊界開始刪除後端
1: a. 2<= p2+p3+p4+p5+p6+p7+p8+p9<=6 數組
大於等於2會保證p1點不是端點或孤立點,由於刪除端點和孤立點是不合理的,小於等於6保證p1點是一個邊界點,而不是一個內部點。等於0時候,周圍沒有等於1的像素,因此p1爲孤立點,等於1的時候,周圍只 有1個灰度等於1的像素,因此是端點(注:端點是周圍有且只能有1個值爲1的像素)。
2:這裏須要知足T(p1)=1 這裏的T(p1)指的是以p2,p3...p8p9 就是p1鄰居點進行輪轉
這裏的輪轉就是從p2開始不斷的與後面的點進行組成元組的格式 好比(p2,p3)(p3,p4) (p4,p5)。。。(p9,p2) 看看這樣組成的全部元組爲(0,1)格式的是否剛好爲1個
假如爲1個而且同時知足另外三個條件,那麼他的樣子大概會是這樣的[[0,1,1] 這樣輪轉中就剛好有一個(0,1) 而且與1相鄰的點必然還有像素值1 這樣就是一個聯通的區域 這時候p1就是邊界點能夠刪除。
[0,1,0]
[0,0,0]]
大概的意思就是這樣,我語文很差,不能說的很清楚,不過大家用本子畫畫就能理解個人意思了 見諒哈!!
3: P2*p4*p6 = 0
4: p4*p6*p8 = 0
這裏 p4,p6出現了兩次 在加上面的輪轉判斷 若是知足邊界點條件 那麼p4,p6中必然會有一個爲0 至於爲何是p4,p6 就是由於這裏是先沿着東南邊界進行細化
將知足的點的索引值存入一個數組中,根據這個數組中點的索引值座標 將圖像中相應位置的點值置爲0 完成一次邊緣細化
第三步:這裏是沿着西北方向進行細化
跟上面一步條件幾乎同樣,惟一改變就是第三和第四個條件,由於這裏是爲了沿着西北方向細化因此要調整爲:p2*p4*p8 = 0 p2*p6*p8 = 0 這裏的p2,p8出現兩次的緣由和 上面一步的p4,p6同樣
將知足的點的索引值存入一個數組中,根據這個數組中點的索引值座標 將圖像中相應位置的點值置爲0 完成一次邊緣細化
最後:反覆執行 第二步和第四步,不斷的進行 左右的細化 直到沒有點在能夠細化 那麼咱們就獲得了 細化後的骨架結構
如今原理已經解釋完畢,那麼就來看看python 是如何實現細化算法的
def neighbours(x,y,image): "Return 8-neighbours of image point P1(x,y) img = image x_1, y_1, x1, y1 = x-1, y-1, x+1, y+1 return [ img[x_1][y], img[x_1][y1], img[x][y1], img[x1][y1], # P2,P3,P4,P5 img[x1][y], img[x1][y_1], img[x][y_1], img[x_1][y_1] ] # P6,P7,P8,P9 def transitions(neighbours): n = neighbours + neighbours[0:1] # P2, P3, ... , P8, P9, P2 return sum( (n1, n2) == (0, 1) for n1, n2 in zip(n, n[1:]) ) # (P2,P3), (P3,P4), ... , (P8,P9), (P9,P2) #將白色靜脈區域細化成骨架結構 def Refine(image): Image_Thinned = image.copy() # deepcopy to protect the original image changing1 = changing2 = 1 # the points to be removed (set as 0) while changing1 or changing2: # iterates until no further changes occur in the image # Step 1 changing1 = [] rows, columns = Image_Thinned.shape # x for rows, y for columns for x in range(1, rows - 1): # No. of rows for y in range(1, columns - 1): # No. of columns P2,P3,P4,P5,P6,P7,P8,P9 = n = neighbours(x, y, Image_Thinned) if (Image_Thinned[x][y] == 1 and # Condition 0: Point P1 in the object regions 2 <= sum(n) <= 6 and # Condition 1: 2<= N(P1) <= 6 The guarantee is not an isolated point and an endpoint or an internal point transitions(n) == 1 and # Condition 2: S(P1)=1 (0,1)The number of rotation of the structure is 1, and the boundary point can be determined by adding other conditions P2 * P4 * P6 == 0 and # Condition 3 Remove the southeast boundary point P4 * P6 * P8 == 0): # Condition 4 changing1.append((x,y)) for x, y in changing1: Image_Thinned[x][y] = 0 # Step 2 changing2 = [] for x in range(1, rows - 1): for y in range(1, columns - 1): P2,P3,P4,P5,P6,P7,P8,P9 = n = neighbours(x, y, Image_Thinned) if (Image_Thinned[x][y] == 1 and # Condition 0 2 <= sum(n) <= 6 and # Condition 1 transitions(n) == 1 and # Condition 2 P2 * P4 * P8 == 0 and # Condition 3 remove the northwest border point P2 * P6 * P8 == 0): # Condition 4 changing2.append((x,y)) for x, y in changing2: Image_Thinned[x][y] = 0 return Image_Thinned
雖然我英文不好,可是我有百度翻譯啊 ,就將我全部的註釋都翻譯成了英文。
這裏我指給出了算法的函數原型,至於怎麼調用中間的代碼我就不給了,反正若是你須要用到這個算法,只要將歸一化到(0,1)二值的話圖片傳入進來調用就好了
在看看細化後的效果圖
原圖:
細化後的圖片:
原圖的靜脈是黑色的 後面我在處理的時候 將黑白二值化翻轉了 白色表明靜脈區域
看完這些有興趣還能夠看看我這篇對指靜脈預處理提取紋理的博客:http://www.cnblogs.com/DOMLX/p/8989836.html
總結概括:
1,看的出來這個細化算法仍是有不足的,沒有那麼的美觀,圖像在分叉點處存在像素的冗餘,即非單像素點,這會使得之後對特徵點的提取至關的麻煩。
這就須要對細化算法進行改進了,這裏能夠採用一些模板算子對圖像進行除去。
2,至於原手指靜脈圖像中的噪聲和陰影等會在骨架圖像中產生各類毛刺,這些毛刺也會影響後期的處理。除去毛刺能夠經過從每一個端點開始沿着費零點搜索,直到
交叉點時中止。在這個過程當中,記錄下每一個端點上遍歷的點數,而後取一個閾值,將小於閾值的那個端點搜索路徑上的置爲0。這樣就完成了對圖像的裁剪。
有興趣還能夠看看:
http://www.cnblogs.com/DOMLX/p/8989836.html 提取紋理特徵
http://www.cnblogs.com/DOMLX/p/8672489.html 指靜脈細化算法
http://www.cnblogs.com/DOMLX/p/8111507.html 指靜脈切割過程
指靜脈識別:
https://www.cnblogs.com/DOMLX/p/9491972.html
如有興趣交流分享技術,可關注本人公衆號,裏面會不按期的分享各類編程教程,和共享源碼,諸如研究分享關於c/c++,python,前端,後端,opencv,halcon,opengl,機器學習深度學習之類有關於基礎編程,圖像處理和機器視覺開發的知識