参考链接:https://github.com/mokosaur/iris-recognition
代码:
import matplotlib.pyplot as plt
import cv2
import math
import numpy as np
from scipy.ndimage.filters import gaussian_filter
import os
import time
def show_segment(save_name,img, x, y, r, x2=None, y2=None, r2=None):
plt.subplots(1, 1)
ax = plt.subplot()
ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 画虹膜
segment = plt.Circle((x, y), r, color='b', fill=False)
ax.add_artist(segment)
# # 画巩膜
# if r2 is not None:
# segment2 = plt.Circle((x2, y2), r2, color='r', fill=False)
# ax.add_artist(segment2)
plt.savefig(save_name)
return plt
def integrate(img, x0, y0, r, arc_start=0, arc_end=1, n=8):
theta = 2 * math.pi / n
integral = 0
for step in np.arange(arc_start * n, arc_end * n, arc_end - arc_start):
x = int(x0 + r * math.cos(step * theta))
y = int(y0 + r * math.sin(step * theta))
integral += img[x, y]
return integral / n
def find_segment(img, x0, y0, minr=0, maxr=500, step=1, sigma=5., center_margin=30, segment_type='iris', jump=1):
max_o = 0
max_l = []
if img.ndim > 2:
img = img[:, :, 0]
margin_img = np.pad(img, maxr, 'edge')
x0 += maxr
y0 += maxr
for x in range(x0 - center_margin, x0 + center_margin + 1, jump):
for y in range(y0 - center_margin, y0 + center_margin + 1, jump):
if segment_type == 'pupil':
l = np.array([integrate(margin_img, y, x, r) for r in range(minr, maxr, step)])
else:
l = np.array([integrate(margin_img, y, x, r, 1 / 8, 3 / 8, n=8) +
integrate(margin_img, y, x, r, 5 / 8, 7 / 8, n=8)
for r in range(minr + abs(x0 - x) + abs(y0 - y), maxr, step)])
l = (l[2:] - l[:-2]) / 2
l = gaussian_filter(l, sigma)
l = np.abs(l)
max_c = np.max(l)
if max_c > max_o:
max_o = max_c
max_l = l
max_x, max_y = x, y
r = np.argmax(l) * step + minr + abs(x0 - x) + abs(y0 - y)
return max_x - maxr, max_y - maxr, r, max_l
def preprocess(image):
img = image[:, :, 0].copy()
img[img > 225] = 30
return cv2.medianBlur(img, 21)
def find_pupil_hough(img):
# circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20,
# param1=50, param2=30, minRadius=10, maxRadius=200)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20,
param1=30, param2=30, minRadius=20, maxRadius=80)
if circles is not None:
circles = np.uint16(np.around(circles))
return circles[0, 0][0], circles[0, 0][1], circles[0, 0][2]
else:
return 0,0,0
def find_iris_id(img, x, y, r):
x, y, r, l = find_segment(img, x, y, minr=max(int(1.25 * r), 100),
sigma=5, center_margin=30, jump=5)
x, y, r, l = find_segment(img, x, y, minr=r - 10, maxr=r + 10,
sigma=2, center_margin=5, jump=1)
return x, y, r
def limit(a,g0=None,g1=None):
if a<=0:
b=0
else:
b=a
if g1>=g0:
gg=g0
else:
gg=g1
return b,gg
def get_eye_roi(image,x, y, r,save_name2):
# 左上角点
x1,_=limit(int(x)-int(r),0,0)
y1,_=limit(int(y)-int(r),0,0)
# 需要裁剪的长宽
w0=image.shape[1]
h0=image.shape[0]
h1=int(y1+2*r)
w1=int(x1+2*r)
_,w1=limit(0,w0,w1)
_,h1=limit(0,h0,h1)
img2=image[y1:h1,x1:w1]
cv2.imwrite(save_name2,img2)
def white_num(image, x, y, r):
a=[]
b=[]
n=0
gray=cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
for i in range(y-r,y):
print(gray[i,x])
a.append(x)
b.append(i)
if gray[i,x]>=180:
n +=1
plt.plot(a,b,linewidth = '2', label = file.split(".")[0], linestyle='-', marker=' ') #画图
plt.show()
return n
# Example usage
if __name__ == '__main__':
path = "img/1/"
save = "img/"
save2 = "img/"
for file in os.listdir(path):
file_name=path+file
image = cv2.imread(file_name)
img = preprocess(image)
x, y, r = find_pupil_hough(img)
print(file_name,r*2)
# 画出虹膜区域
save_name=save+file+".png"
show_segment(save_name,image, x, y, r)
# # 裁剪虹膜roi的外接圆
# if r>=5:
# save_name2=save2+file
# get_eye_roi(image,x, y, r,save_name2)
# # 计算白点的数量
# n=white_num(image, x, y, r)
# print("白点数量:",n)