【问题标题】:Opencv: How can I get the eye colorOpencv:我怎样才能得到眼睛的颜色
【发布时间】:2018-01-12 19:27:06
【问题描述】:

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

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

我最好的办法是检测瞳孔,这是眼睛中唯一具有每只眼睛共同颜色(黑色)的部分。我想得到一些想法来做到这一点。

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

任何想法都将不胜感激。

谢谢。

【问题讨论】:

  • tesnorflow 图像分类
  • 您只是想将眼睛分类为“蓝色”还是“非蓝色”?如果是这样,您可以查看整个图像的颜色直方图,并寻找不会出现在任何颜色的皮肤中的蓝色调的尖峰。您应该能够识别图像中是否存在蓝色调,或者缺少蓝色。
  • 您的问题是什么?你想区分多少种眼睛颜色?蓝色和棕色?绿色 蓝色 棕色?甚至不同深浅的棕色?我会接受@struthersneil 的建议。裁剪这些图片的中心并对色调进行分类。棕色和蓝色的眼睛应该有很大的区别

标签: python opencv image-processing


【解决方案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:如有错误请指正,欢迎提出建议。

【讨论】:

    【解决方案2】:

    其实你检测瞳孔形状的想法很好,但是你的图片还不够好,不能直接做。一种简单的方法是对它们进行预处理以删除所有无用的数据。

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

    • 转灰度

    • 做一个高通滤波器来消除所有小的颜色波动(你有非常明显的颜色,所以它应该很好地增强边框)

    Link to example filtered pic

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

    Link to example thresholded pic

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

    【讨论】:

    • 感谢您的回答。您使用的过滤器的值是多少?我尝试按照您的建议应用它们,但没有得到类似的结果。
    • 我正在使用 Gimp 过滤器,它比您可以编码的标准高通和阈值更复杂一些,但它可以让您很好地了解要执行的操作。这里有我提取的参数: 对于高通:标准化:0% 色调:0 饱和度:100% 亮度:100% 伽玛值:1 对比度:0% 均衡:0% 对于阈值:我只是把对比度设置为 100% (只剩下极值)
    猜你喜欢
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 2012-03-14
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多