一、模型输出的数据
![](https://i-blog.csdnimg.cn/blog_migrate/38787aecab20dd16441d68c5913e1747.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a5805613dcb076ae9db628aab19071df.jpeg)
二、瞳孔定位
由于上下眼皮对眼球的遮挡,因此只有左边的边线与右边的边线的曲率是最接近眼球的,可从左边取两个点,从右边取一个点,以此三点来定位圆心。
import os
import cv2 as cv
import numpy as np
dpath='F:/data/data4/preds/'
files=os.listdir(dpath)
img=cv.imread(dpath+files[0],cv.IMREAD_GRAYSCALE)
def detect_circle(img):
i=50#目测前50列都是空白,减少循环次数,也可从0开始
flag=1
while(flag):
if len(np.where(img[:,i]==255)[0].tolist())>0:
arr_1=np.where(img[:,i]==255)[0].tolist()
arr_2=np.where(img[:,i+5]==255)[0].tolist()
A=(arr_1[0],i)
B=(arr_2[-1],i+5)#下眼皮较上眼皮遮挡较少,B、C取眼球下半部分
flag=0
else:
i+=1
flag=1
i=img.shape[1]-50#从最后往前遍历
while(flag):
if len(np.where(img[:,i]==255)[0].tolist())>0:
arr_3=np.where(img[:,i]==255)[0].tolist()
C=(arr_1[-1],i)
flag=0
else:
i-=1
return A,B,C
A,B,C=detect_circle(img)
x1,y1=A
x2,y2=B
x3,y3=C
print(A,B,C)
<<<(130, 142) (145, 147) (134, 392)
#根据AB、BC的中垂线交点解出圆心Q
#t1、t2为了简化和避免重复计算而提取出的重复部分
t1=(x1-x2)/(y1-y2)
t2=(x3-x2)/(y3-y2)
x0=int((y3-y1-t1*(x1+x2)+t2*(x3+x2))/2/(t2-t1))
y0=int((t1*t2*(x3-x1)-t2*(y1+y2)+t1*(y3+y2))/2/(t1-t2))
Q=(x0,y0)
print(Q)
<<<(96, 267)
cv.circle(img,(y0,x0), 10, 64, -1)#注意cv中(col,row),10是半径,64是像素值,-1不知道
三、水平校正
def detection(img):#检测出左端点和右端点
i=0
flag=1
msk=np.zeros(img.shape,dtype=np.uint8)
msk[np.where((img>96) & (img<192))]=255 #模型输出的眼睑区的像素值为127,这里随便取了个范围
while flag:
if len(np.where(msk[:,i]==255)[0].tolist())>0:
arr=np.where(msk[:,i]==255)[0].tolist()
A=(arr[0],i)
flag=0
else:
i+=1
i=img.shape[1]-1
flag=1
while flag:
if len(np.where(msk[:,i]==255)[0].tolist())>0:
arr=np.where(msk[:,i]==255)[0].tolist()
B=(arr[-1],i)
flag=0
else:
i-=1
return A,B
img=cv.imread(dpath+file,cv.IMREAD_GRAYSCALE)
A,B=detection(img)
x1,y1=A
x2,y2=B
rows,cols=img.shape
theta=np.arctan((x1-x2)/(y1-y2))#同样需要注意坐标,如果除反了,图像旋转之后就竖起来了
M=cv.getRotationMatrix2D((cols/2,rows/2),theta,1)
dst=cv.warpAffine(img,M,(cols,rows))