微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 Python 3 中的指纹特征提取器中提取细节终止和分叉值

如何解决从 Python 3 中的指纹特征提取器中提取细节终止和分叉值

我最近尝试了 Utkarsh-Deshmukh (https://github.com/Utkarsh-Deshmukh/Fingerprint-Feature-Extraction) 的新指纹特征提取器库,它的效果令人惊奇。问题是我需要从库中提取终止和分叉值。我使用包含在 github 链接中的此代码获取功能分岔和终止:

import fingerprint_feature_extractor

img = cv2.imread('image_path',0)
FeaturesTerminations,FeaturesBifurcations = fingerprint_feature_extractor.extract_minutiae_features(img,showResult=True,spurIoUsMinutiaeThresh=10)

我尝试使用 print() 命令查看 FeaturesBifurcations 中的内容,但我无法理解输出的含义。

print() command on FeaturesBifurcations

我需要的是如下所示的值,其中第一列和第二列表示 xy 坐标,第三列表示方向,第四列表示类型:

minutiaes bifurcations (marked with 1 in the last column) and terminations (marked with 0 in the last column) values extracted from fingerprint

我尝试阅读库中的类,我认为我可以获得这些值(库中明确说明了特征位置、方向和类型),但我不知道如何提取这些值。这是指纹特征提取器库中的内容

import cv2
import numpy as np
import skimage.morphology
from skimage.morphology import convex_hull_image,erosion
from skimage.morphology import square
import math

class MinutiaeFeature(object):
  def __init__(self,locX,locY,Orientation,Type):
    self.locX = locX;
    self.locY = locY;
    self.Orientation = Orientation;
    self.Type = Type;

class FingerprintFeatureExtractor(object):
  def __init__(self):
    self._mask = []
    self._skel = []
    self.minutiaeTerm = []
    self.minutiaeBif = []

  def __skeletonize(self,img):
    img = np.uint8(img > 128)
    self._skel = skimage.morphology.skeletonize(img)
    self._skel = np.uint8(self._skel) * 255
    self._mask = img * 255

  def __computeAngle(self,block,minutiaeType):
    angle = []
    (blkRows,blkCols) = np.shape(block);
    CenterX,CenterY = (blkRows - 1) / 2,(blkCols - 1) / 2
    if (minutiaeType.lower() == 'termination'):
        sumVal = 0;
        for i in range(blkRows):
            for j in range(blkCols):
                if ((i == 0 or i == blkRows - 1 or j == 0 or j == blkCols - 1) and block[i][j] != 0):
                    angle.append(-math.degrees(math.atan2(i - CenterY,j - CenterX)))
                    sumVal += 1
                    if (sumVal > 1):
                        angle.append(float('nan'))
        return (angle)

    elif (minutiaeType.lower() == 'bifurcation'):
        (blkRows,blkCols) = np.shape(block);
        CenterX,(blkCols - 1) / 2
        angle = []
        sumVal = 0;
        for i in range(blkRows):
            for j in range(blkCols):
                if ((i == 0 or i == blkRows - 1 or j == 0 or j == blkCols - 1) and block[i][j] != 0):
                    angle.append(-math.degrees(math.atan2(i - CenterY,j - CenterX)))
                    sumVal += 1
        if (sumVal != 3):
            angle.append(float('nan'))
        return (angle)

  def __getTerminationBifurcation(self):
    self._skel = self._skel == 255;
    (rows,cols) = self._skel.shape;
    self.minutiaeTerm = np.zeros(self._skel.shape);
    self.minutiaeBif = np.zeros(self._skel.shape);

    for i in range(1,rows - 1):
        for j in range(1,cols - 1):
            if (self._skel[i][j] == 1):
                block = self._skel[i - 1:i + 2,j - 1:j + 2];
                block_val = np.sum(block);
                if (block_val == 2):
                    self.minutiaeTerm[i,j] = 1;
                elif (block_val == 4):
                    self.minutiaeBif[i,j] = 1;

    self._mask = convex_hull_image(self._mask > 0)
    self._mask = erosion(self._mask,square(5))  # Structuing element for mask erosion = square(5)
    self.minutiaeTerm = np.uint8(self._mask) * self.minutiaeTerm

  def __removeSpurIoUsMinutiae(self,minutiaeList,img,thresh):
    img = img * 0;
    SpurIoUsMin = [];
    numPoints = len(minutiaeList);
    D = np.zeros((numPoints,numPoints))
    for i in range(1,numPoints):
        for j in range(0,i):
            (X1,Y1) = minutiaeList[i]['centroid']
            (X2,Y2) = minutiaeList[j]['centroid']

            dist = np.sqrt((X2-X1)**2 + (Y2-Y1)**2);
            D[i][j] = dist
            if(dist < thresh):
                SpurIoUsMin.append(i)
                SpurIoUsMin.append(j)

    SpurIoUsMin = np.unique(SpurIoUsMin)
    for i in range(0,numPoints):
        if(not i in SpurIoUsMin):
            (X,Y) = np.int16(minutiaeList[i]['centroid']);
            img[X,Y] = 1;

    img = np.uint8(img);
    return(img)

  def __cleanMinutiae(self,img):
    self.minutiaeTerm = skimage.measure.label(self.minutiaeTerm,connectivity=2);
    RP = skimage.measure.regionprops(self.minutiaeTerm)
    self.minutiaeTerm = self.__removeSpurIoUsMinutiae(RP,np.uint8(img),10);

  def __performFeatureExtraction(self):
    FeaturesTerm = []
    self.minutiaeTerm = skimage.measure.label(self.minutiaeTerm,connectivity=2);
    RP = skimage.measure.regionprops(np.uint8(self.minutiaeTerm))

    WindowSize = 2  # --> For Termination,the block size must can be 3x3,or 5x5. Hence the window selected is 1 or 2
    FeaturesTerm = []
    for num,i in enumerate(RP):
        print(num)
        (row,col) = np.int16(np.round(i['Centroid']))
        block = self._skel[row - WindowSize:row + WindowSize + 1,col - WindowSize:col + WindowSize + 1]
        angle = self.__computeAngle(block,'Termination')
        if(len(angle) == 1):
            FeaturesTerm.append(MinutiaeFeature(row,col,angle,'Termination'))

    FeaturesBif = []
    self.minutiaeBif = skimage.measure.label(self.minutiaeBif,connectivity=2);
    RP = skimage.measure.regionprops(np.uint8(self.minutiaeBif))
    WindowSize = 1  # --> For Bifurcation,the block size must be 3x3. Hence the window selected is 1
    for i in RP:
        (row,'Bifurcation')
        if(len(angle) == 3):
            FeaturesBif.append(MinutiaeFeature(row,'Bifurcation'))
    return (FeaturesTerm,FeaturesBif)

  def extractMinutiaeFeatures(self,img):
    self.__skeletonize(img)

    self.__getTerminationBifurcation()

    self.__cleanMinutiae(img)

    FeaturesTerm,FeaturesBif = self.__performFeatureExtraction()
    return(FeaturesTerm,FeaturesBif)

  def showResults(self):
    BifLabel = skimage.measure.label(self.minutiaeBif,connectivity=2);
    Termlabel = skimage.measure.label(self.minutiaeTerm,connectivity=2);

    minutiaeBif = Termlabel * 0;
    minutiaeTerm = BifLabel * 0;

    (rows,cols) = self._skel.shape
    dispImg = np.zeros((rows,cols,3),np.uint8)
    dispImg[:,:,0] = 255*self._skel;
    dispImg[:,1] = 255*self._skel;
    dispImg[:,2] = 255*self._skel;

    RP = skimage.measure.regionprops(BifLabel)
    for idx,i in enumerate(RP):
        (row,col) = np.int16(np.round(i['Centroid']))
        minutiaeBif[row,col] = 1;
        (rr,cc) = skimage.draw.circle_perimeter(row,3);
        skimage.draw.set_color(dispImg,(rr,cc),(255,0));

    RP = skimage.measure.regionprops(Termlabel)
    for idx,col) = np.int16(np.round(i['Centroid']))
        minutiaeTerm[row,(0,255));

    cv2.imshow('a',dispImg);
    cv2.waitKey(0)

def extract_minutiae_features(img,showResult=False):
  feature_extractor = FingerprintFeatureExtractor()
  FeaturesTerm,FeaturesBif = feature_extractor.extractMinutiaeFeatures(img)

  if(showResult):
      feature_extractor.showResults()

  return(FeaturesTerm,FeaturesBif)

有没有办法从这个库中提取位置、方向和类型浮点(和/或整数)值?或者有没有一种方法或库可以将这些列表绘制成笛卡尔坐标或极坐标?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。