手指靜脈細化算法過程原理解析 以及python實現細化算法


 

原文作者:aircraft

原文地址:https://www.cnblogs.com/DOMLX/p/8672489.html

 

 

 文中的一些圖片以及思想很多都是參考https://www.cnblogs.com/My-code-z/p/5712524.html 大佬的思想 以及自己做一些個人理解的補充

  若想下載指靜脈識別入門代碼:https://github.com/lmskyle/process

  細化算法原理理解起來並不難,借助矩陣九宮格來實現。將九宮格定義並且編號成如下格式。

  在講解之前有必要先看看書中是怎么說的:

 

 

 

 

 

  書中說的還是比較簡潔的,畢竟是大牛寫的,他們覺得很簡單容易理解的東西,我們看起來就未必是這樣了。好了閑話不多說 進入主題。

  第一步:為了不影響原圖像的一些其他操作,先將原圖像拷貝一份用來細化處理,在將細化后圖片返回出去。

  第二步:就跟書里看的那樣,需要滿足四個條件來才能進行刪除該點像素。這里進行的是沿着東南邊界開始刪除

      1: a. 2<= p2+p3+p4+p5+p6+p7+p8+p9<=6  

            大於等於2會保證p1點不是端點或孤立點,因為刪除端點和孤立點是不合理的,小於等於6保證p1點是一個邊界點,而不是一個內部點。等於0時候,周圍沒有等於1的像素,所以p1為孤立點,等於1的時候,周圍只            有1個灰度等於1的像素,所以是端點(注:端點是周圍有且只能有1個值為1的像素)。

          

       這里需要滿足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]]  

 

            大概的意思就是這樣,我語文不好,不能說的很清楚,不過你們用本子畫畫就能理解我的意思了  見諒哈!!

          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,機器學習深度學習之類有關於基礎編程,圖像處理和機器視覺開發的知識


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM