掌纹识别python 预处理-提取ROI
本项目使用香港理工大学的掌纹公开库(v2)
参考资料:
https://zhuanlan.zhihu.com/p/365301097
https://ieeexplore.ieee.org/document/1227981
step1 Apply a lowpass filter
def low_Gaussian(Crop_img):
"""
/2.2 Low-pass(Gaussian) Filter//
//为了去除边界效应,滤波前我们将图像四周宽为7个像素的部分置为黑色背景
"""
roi = Crop_img
rows,cols=roi.shape
crow,ccol=int(rows/2),int(cols/2)
mask=np.zeros((rows,cols),np.uint8)
mask[crow-(crow-7):crow+(crow-7),ccol-(ccol-7):ccol+(ccol-7)]=1
roi = roi*mask
processed = cv2.GaussianBlur(roi, (15, 15), 2,2)
// threshold Tp = 20
a,Binary_img=threshold(processed, 20, 1, 0)
#plt.imshow( Binary_img, cmap='binary')
return Binary_img
Step 2,Step 3.Obtain the boundaries of the gaps ,Compute the tangent of the two gaps.
def GetPointTopandBottom(Binary_img):
rows,cols=Binary_img.shape
//b)Find Internal Reference Point
for i in range(0,rows):
for j in range(0,cols):
if Binary_img[i][j] == 1:
out_top=(j,i)
GetOutofLoop
for i in range(rows-1,0,-1):
for j in range(0,cols):
if Binary_img[i][j] == 1:
Out_bottom=(j,i)
GetOutofLoop
gap_x=0
for i in range(0,cols,1):
gap_width = 0
for j in range(0,rows):
if Binary_img[j][i] == 0:
gap_width+=1
if gap_width < 200:
gap_x = i
GetOutofLoop
In_top_x = gap_x
In_bottom_x = gap_x
In_top_y=0
In_bottom_y=0
center_y =int( rows / 2)
for i in range(center_y,0,-1):
if Binary_img[i,gap_x] == 1:
In_top_y = i
GetOutofLoop
for i in range(center_y,rows):
if Binary_img[i,gap_x] == 1:
In_bottom_y = i
GetOutofLoop
In_top=(In_top_x,In_top_y)
In_bottom=(In_bottom_x,In_bottom_y)
return out_top,Out_bottom,In_top,In_bottom
事实上,二值图像中只有一个轮廓,也就是说contours只有一个。这里由于先前处理不好导致某些图像分裂,会出现多个contours的情况。在低通高斯滤波我们可以用去除噪声的方法对二值图像进行处理,就可以避免这种情况,删掉冗余的代码。
// boundary tracking
#//2.5.1 Find Contours//
def FindContours(Binary_img,Out_top,Out_bottom,In_top,In_bottom):
Out_top_j = 0; Out_bottom_j = 0; In_top_j = 0;In_bottom_j = 0
reference_point_num = 0
contours, hierarchy=findContours(Binary_img,mode=cv2.RETR_EXTERNAL,method= cv2.CHAIN_APPROX_NONE )
Contours=np.zeros(Binary_img.shape)
for i in range(len(contours)):
for j in range(0,len(contours[i])):
if (contours[i][j][0] == Out_top).all():
Out_top_j = j
reference_point_num += 1
#print("Out_top_j:",Out_top_j)
if (contours[i][j][0] == Out_bottom).all():
Out_bottom_j = j
reference_point_num += 1
#print("Out_top_j:", Out_bottom_j )
if (contours[i][j][0] == In_top).all():
In_top_j = j
reference_point_num += 1
# print("Out_top_j:", In_top_j)
if (contours[i][j][0] == In_bottom).all():
In_bottom_j=j
reference_point_num += 1
#print("Out_top_j:", In_bottom_j)
assert reference_point_num==4
Top_x = 0
Bottom_x = 0
Top_y_list = []
Bottom_y_list = []
for i in range(len(contours)):
for j in range(Out_top_j,In_top_j,1):
try:
Contours[contours[i][j][0][1],contours[i][j][0][0]] = 1
except:
pass
for j in range(In_bottom_j,Out_bottom_j,1):
try:
Contours[contours[i][j][0][1], contours[i][j][0][0]] = 1
except:
pass
for i in range(len(contours)):
for j in range(Out_top_j, In_top_j, 1):
try:
if contours[i][j][0][0] > Top_x:
Top_x = contours[i][j][0][0]
except:
pass
for j in range(In_bottom_j, Out_bottom_j, 1):
try:
if contours[i][j][0][0] > Bottom_x:
Bottom_x = contours[i][j][0][0]
except:
pass
for i in range(len(contours)):
for j in range(Out_top_j, In_top_j, 1):
try:
if contours[i][j][0][0] == Top_x:
Top_y_list.append(contours[i][j][0][1])
except:pass
for j in range(In_bottom_j, Out_bottom_j, 1):
try:
if contours[i][j][0][0] == Bottom_x:
Bottom_y_list.append(contours[i][j][0][1])
except:pass
Top_y = np.mean(Top_y_list)
Bottom_y = np.mean(Bottom_y_list)
return [Top_x,Top_y],[Bottom_x,Bottom_y],Contours
Step 4,5. determine the origin of the coordinate system.Extract a subimage of a fixed size based on the coordinate system.
def GetROI(Top_point, Bottom_point,img):
"""
//2.6 Build a Coordinate System on the Original Image//
"""
Top_point[0]+=40
Bottom_point[0]+=40
//中垂线中心位置
Origin_X =(Top_point[0]+Bottom_point[0])/2
Origin_Y = (Top_point[1]+Bottom_point[1])/2
Origin2d =(Origin_X,Origin_Y)
// 斜率,即tan
Slope_y_axis = (Top_point[1]-Bottom_point[1])/(Top_point[0]-Bottom_point[0])
Slope_x_axis = -1 / Slope_y_axis
angle = -atan(1 / Slope_y_axis) * (180 / math.pi)
rot_mat = cv2.getRotationMatrix2D(Origin2d, angle, 1)
// 按照斜率旋转
img_rotated_by_alpha = cv2.warpAffine(img , rot_mat, (img.shape[1], img.shape[0]),1,0)
ROI = np.asarray(img)[int(Origin_Y - 128 / 2):int(Origin_Y - 128 / 2+128),int(Origin_X + 50):int(Origin_X + 50+128)]
return ROI,[int(Origin_X + 50),int(Origin_X + 50+128),int(Origin_Y - 128 / 2),int(Origin_Y - 128 / 2+128)]