Простой процесс обработки изображения должен помочь вам достичь вашей цели.
Сначала загрузите изображение в оттенках серого.Я думаю, что пороговый метод Оцу достаточно надежен, чтобы извлечь область зрачка глаза.Дополнительный морфологический процесс требуется для удаления шума и незаполненных областей
![enter image description here](https://i.stack.imgur.com/VMyiq.png)
Затем, используя анализ подключенных компонентов, мы можем выделить область зрачка для дальнейшей обработки.
![enter image description here](https://i.stack.imgur.com/9Pq05.png)
С этой областью мы можем получить край, вычитая расширенную область с исходной областью, как показано ниже.
![enter image description here](https://i.stack.imgur.com/YLnZX.png)
Наконец, мы можем запустить подгонку окружности или алгоритм подбора эллипса, чтобы получить соответствующую форму,
![enter image description here](https://i.stack.imgur.com/nbCCG.png)
Подгонка круга показана красным, а эллипс - зеленым.Оба возвращают одну и ту же центральную позицию, хотя и слегка различную форму.
Здесь используется код.Я уменьшаю изображение, чтобы ускорить процесс, но оно будет работать так же, используя оригинальный размер.
import cv2
import numpy as np
img = cv2.imread('eye.jpg',0)
small_img = cv2.resize(img,(0,0),fx = 0.25, fy = 0.25)
r,c = small_img.shape
# Threshold objs
_, thresh = cv2.threshold(small_img,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Morphological close process to cluster nearby objects
bin_img = cv2.dilate(thresh, None,iterations = 5)
bin_img = cv2.erode(bin_img, None,iterations = 5)
# Analyse connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_img)
# Find circle center and radius
# Radius calculated by averaging the height and width of bounding box
bin_eye = np.zeros((r,c))
cnt_label = labels[r/2,c/2]
bin_eye[labels == cnt_label] = 255
area = stats[cnt_label][4]
radius = np.sqrt(area / np.pi)
cnt_pt = ((centroids[cnt_label][0]),(centroids[cnt_label][1]))
# fit ellipse
bin_eye_large = cv2.dilate(bin_eye, None,iterations = 1)
# Get ellipse edge
edge_eye = bin_eye_large - bin_eye
# extract location points for fitting
ellip_pts = np.where(edge_eye > 0)
ellip_pts = np.transpose(ellip_pts)
temp = np.copy(ellip_pts[:,0])
ellip_pts[:,0] = ellip_pts[:,1]
ellip_pts[:,1] = temp
# fit ellipse
ellip = cv2.fitEllipse(ellip_pts)
# Display final result
edges_color = cv2.cvtColor(small_img,cv2.COLOR_GRAY2BGR)
cv2.circle(edges_color,(int(cnt_pt[0]),int(cnt_pt[1])),int(radius),(0,0,255),1)
cv2.circle(edges_color,(int(cnt_pt[0]),int(cnt_pt[1])),5,(0,0,255),1)
cv2.ellipse(edges_color,ellip, (0,255,0))
cv2.circle(edges_color,(int(ellip[0][0]),int(ellip[0][1])),5,(0,255,0),1)
cv2.imshow('edges_color',edges_color)
cv2.imshow('bin_img',bin_img)
cv2.imshow('eye_label',bin_eye)
cv2.imshow('eye_edge',edge_eye)
cv2.waitKey(0)