我正在使用dblib来获取面部的眼睛。以下是一些结果示例。
我尝试了几种方法来实现目标。例如,我试图根据project检测眼睛的中心;从中可以很容易地发现瞳孔和虹膜,但是,我没有取得好成绩。我也试过使用Hough Circles但在某些情况下结果非常糟糕。
我最好的选择是检测瞳孔,瞳孔是眼睛的唯一部分,每只眼睛都有一个共同的颜色(黑色)。我想得到一些想法。
我的第一个想法是设置一个区域(在x轴上介于20和60之间),然后,在灰度级中,使暗像素(例如小于25)变为黑色,其余为白色。这将创建一个掩模,可以模糊使用Hough Circles并检测瞳孔的区域。最后,我可以设置虹膜的半径。
任何想法都会受到赞赏。
感谢。
答案 0 :(得分:0)
实际上你的检测瞳孔形状的想法很好,但是你的照片还不够直接。一种简单的方法是预处理那些删除所有无用的数据。
我做了一些例子,用你的一张原始照片向你展示(在Gimp上)
转到灰度
使用高通滤镜去除所有小的颜色波动(你有非常明显的颜色,所以它应该很好地增强边框)
Link to example thresholded pic
在这三个步骤之后,您应该有足够的数据来运行形状检测。
答案 1 :(得分:-1)
到目前为止,我读过的大多数答案都说使用霍夫圆法来检测虹膜区域,但它并不真正适用于所有图像。
所以我的方法很简单,包括以下步骤
注意:将高分辨率图像作为输入传递以获得更好的结果。如果您传递 480x620、320x240 等低分辨率图像,您最终可能会得到较差的结果。
下面是相同的代码
import cv2
import imutils
from imutils import face_utils
import dlib
import numpy as np
import webcolors
flag=0
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
img= cv2.imread('blue2.jpg')
img_rgb= cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #convert to RGB
#cap = cv2.VideoCapture(0) #turns on the webcam
(left_Start, left_End) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
#points for left eye and right eye
(right_Start, right_End) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
def find_color(requested_colour): #finds the color name from RGB values
min_colours = {}
for name, key in webcolors.CSS3_HEX_TO_NAMES.items():
r_c, g_c, b_c = webcolors.hex_to_rgb(name)
rd = (r_c - requested_colour[0]) ** 2
gd = (g_c - requested_colour[1]) ** 2
bd = (b_c - requested_colour[2]) ** 2
min_colours[(rd + gd + bd)] = key
closest_name = min_colours[min(min_colours.keys())]
return closest_name
#ret, frame=cap.read()
#frame = cv2.flip(frame, 1)
#cv2.imshow(winname='face',mat=frame)
gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
# detect dlib face rectangles in the grayscale frame
dlib_faces = detector(gray, 0)
for face in dlib_faces:
eyes = [] # store 2 eyes
# convert dlib rect to a bounding box
(x,y,w,h) = face_utils.rect_to_bb(face)
cv2.rectangle(img_rgb,(x,y),(x+w,y+h),(255,0,0),1) #draws blue box over face
shape = predictor(gray, face)
shape = face_utils.shape_to_np(shape)
leftEye = shape[left_Start:left_End]
# indexes for left eye key points
rightEye = shape[right_Start:right_End]
eyes.append(leftEye) # wrap in a list
eyes.append(rightEye)
for index, eye in enumerate(eyes):
flag+=1
left_side_eye = eye[0] # left edge of eye
right_side_eye = eye[3] # right edge of eye
top_side_eye = eye[1] # top side of eye
bottom_side_eye = eye[4] # bottom side of eye
# calculate height and width of dlib eye keypoints
eye_width = right_side_eye[0] - left_side_eye[0]
eye_height = bottom_side_eye[1] - top_side_eye[1]
# create bounding box with buffer around keypoints
eye_x1 = int(left_side_eye[0] - 0 * eye_width)
eye_x2 = int(right_side_eye[0] + 0 * eye_width)
eye_y1 = int(top_side_eye[1] - 1 * eye_height)
eye_y2 = int(bottom_side_eye[1] + 0.75 * eye_height)
# draw bounding box around eye roi
#cv2.rectangle(img_rgb,(eye_x1, eye_y1), (eye_x2, eye_y2),(0,255,0),2)
roi_eye = img_rgb[eye_y1:eye_y2 ,eye_x1:eye_x2] # desired EYE Region(RGB)
if flag==1:
break
x=roi_eye.shape
row=x[0]
col=x[1]
# this is the main part,
# where you pick RGB values from the area just below pupil
array1=roi_eye[row//2:(row//2)+1,int((col//3)+3):int((col//3))+6]
array1=array1[0][2]
array1=tuple(array1) #store it in tuple and pass this tuple to "find_color" Funtion
print(find_color(array1))
cv2.imshow("frame",roi_eye)
cv2.waitKey(0)
cv2.destroyAllWindows()
以下是一些示例。
现在这是上面图片作为输入时我们代码的输出:lightsteelblue
当上面的图像作为输入时我们代码的输出:saddlebrown
当上面的图像作为输入时我们代码的输出:sienna(shade of brown)
当上面的图像作为输入时我们代码的输出:darkgrey
因此,您可以看到结果与实际眼睛颜色的接近程度。正如我已经提到的,这对高分辨率图像非常有效。
PS:如果错了,请纠正我,欢迎提出建议。