如何解决从 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 坐标,第三列表示方向,第四列表示类型:
我尝试阅读库中的类,我认为我可以获得这些值(库中明确说明了特征位置、方向和类型),但我不知道如何提取这些值。这是指纹特征提取器库中的内容:
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 举报,一经查实,本站将立刻删除。