Opencv:我怎样才能获得眼睛的颜色

时间:2017-08-04 19:06:38

标签: python opencv image-processing

我正在使用dblib来获取面部的眼睛。以下是一些结果示例。

eye example eye example eye example eye example

我尝试了几种方法来实现目标。例如,我试图根据project检测眼睛的中心;从中可以很容易地发现瞳孔和虹膜,但是,我没有取得好成绩。我也试过使用Hough Circles但在某些情况下结果非常糟糕。

我最好的选择是检测瞳孔,瞳孔是眼睛的唯一部分,每只眼睛都有一个共同的颜色(黑色)。我想得到一些想法。

我的第一个想法是设置一个区域(在x轴上介于20和60之间),然后,在灰度级中,使暗像素(例如小于25)变为黑色,其余为白色。这将创建一个掩模,可以模糊使用Hough Circles并检测瞳孔的区域。最后,我可以设置虹膜的半径。

任何想法都会受到赞赏。

感谢。

2 个答案:

答案 0 :(得分:0)

实际上你的检测瞳孔形状的想法很好,但是你的照片还不够直接。一种简单的方法是预处理那些删除所有无用的数据。

我做了一些例子,用你的一张原始照片向你展示(在Gimp上)

  • 转到灰度

  • 使用高通滤镜去除所有小的颜色波动(你有非常明显的颜色,所以它应该很好地增强边框)

Link to example filtered pic

  • 在图片上应用阈值以消除剩余波动(您可以通过分析灰度图像颜色直方图来计算参考阈值)

Link to example thresholded pic

在这三个步骤之后,您应该有足够的数据来运行形状检测。

答案 1 :(得分:-1)

到目前为止,我读过的大多数答案都说使用霍夫圆法来检测虹膜区域,但它并不真正适用于所有图像。

所以我的方法很简单,包括以下步骤

  • 从图像中检测人脸
  • 从面部找出眼睛区域
  • 获取瞳孔区域正下方的RGB值(从而获得虹膜区域RGB值)
  • 并将获得的RGB值传递给find_color函数

注意:将高分辨率图像作为输入传递以获得更好的结果。如果您传递 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:如果错了,请纠正我,欢迎提出建议。