OpenCV detectando el color de la piel invariante con cambios de iluminación


8

Tengo que capturar el color de la piel independientemente de la iluminación. Usé los siguientes criterios (usando hsv y rgb) pero no funciona:

int h = get_hue(...);
int s = get_saturation(...);
int r = get_red_component(...);
int g = get_green_component(...);
int b = get_blue_component(...);

if ((h<38)&&(h>6)&&(s>0.23)&&(s<0.68)){
    // skin color
}
else if ((r>95) && (g>40) && (b>20) && 
         ((maximum(r,g,b)-minimum(r,g,b))>15) && 
         (abs(r-g)>15)&&(r>g)&&(r>b)){
   // also skin color
}

Funciona por la mañana cuando mi piel está iluminada, pero por la noche no funciona.

Cualquier ayuda será apreciada. Gracias por adelantado. (PD: mi piel no es blanca).


2
¿Podría proporcionar imágenes de muestra y tal vez describir un poco mejor la salida deseada? ¿Desea "clasificar" los píxeles de la imagen en clases que no sean skin y skin ? Además, podría intentar justificar sus criterios, tal vez no sea tan malo, pero nos ayudaría a mejorarlo si entendiéramos cómo se le ocurrió.
Penélope

2
Esto podría ayudar (es decir, para eliminar primero los efectos de la iluminación): dsp.stackexchange.com/a/459/35
datageist

estos dos criterios que acabo de obtener de google y sí, tengo que distinguir la piel de las áreas sin piel
Roney Island


1
Aquí hay una vieja pregunta mía, tal vez podría ayudar: dsp.stackexchange.com/questions/1625/…
nkint

Respuestas:


4

En mi experiencia, el mejor método para esto es convertirlo al espacio de color Lab. L representa la luz, y a y b son independientes de la luz. OpenCV admite la conversión de escala de color de laboratorio.


He visto el mismo comentario en el manual de reconocimiento facial (Springer). El laboratorio debería ser un mejor espacio de color.
sansuiso

2

Para este caso especial, recomiendo leer sobre el modelo LAB Color.

Y con respecto al modelo LAB Color, lea sobre Delta E. La distancia entre 2 colores. Más detalles sobre el espacio de color se pueden encontrar aquí: http://www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

Nunca he intentado el modelo de color LAB a través de OpenCV, ya que es una molestia convertir de RGB a LAB y viceversa (requiere un paso inmediato).

Pero he explorado Delta E en MatLab con gran éxito. Primero debe seleccionar la máscara, dibujar un pequeño ROI en el video / imagen y el programa encontrará exactamente el mismo tono de color que la máscara que seleccionó a través del ROI.

Otra opción es también mirar en la textura. A short here here: http://books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFC-AAAAA = 0CDUQ6AEwAQ # v = onepage & q = skin% 20th umbraling% 20from% 20texture & f = false

Esto es básicamente entrenar una base de datos de imágenes. Comente aquí si necesita ayuda para entrenar la base de datos de imágenes o la conversión de ColorSpace. Un poco ocupado, por lo que la respuesta son solo sugerencias que puede hacer. Salud.


1

prueba esto:

''' Detect human skin tone and draw a boundary around it.
Useful for gesture recognition and motion tracking.

Inspired by: http://stackoverflow.com/a/14756351/1463143

Date: 08 June 2013
'''

# Required moduls
import cv2
import numpy

# Constants for finding range of skin color in YCrCb
min_YCrCb = numpy.array([0,133,77],numpy.uint8)
max_YCrCb = numpy.array([255,173,127],numpy.uint8)

# Create a window to display the camera feed
cv2.namedWindow('Camera Output')

# Get pointer to video frames from primary device
videoFrame = cv2.VideoCapture(0)

# Process the video frames
keyPressed = -1 # -1 indicates no key pressed

while(keyPressed < 0): # any key pressed has a value >= 0

    # Grab video frame, decode it and return next video frame
    readSucsess, sourceImage = videoFrame.read()

    # Convert image to YCrCb
    imageYCrCb = cv2.cvtColor(sourceImage,cv2.COLOR_BGR2YCR_CB)

    # Find region with skin tone in YCrCb image
    skinRegion = cv2.inRange(imageYCrCb,min_YCrCb,max_YCrCb)

    # Do contour detection on skin region
    contours, hierarchy = cv2.findContours(skinRegion, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # Draw the contour on the source image
    for i, c in enumerate(contours):
        area = cv2.contourArea(c)
        if area > 1000:
            cv2.drawContours(sourceImage, contours, i, (0, 255, 0), 3)

    # Display the source image
    cv2.imshow('Camera Output',sourceImage)

    # Check for user input to close program
    keyPressed = cv2.waitKey(1) # wait 1 milisecond in each iteration of while loop

# Close window and camera after exiting the while loop
cv2.destroyWindow('Camera Output')
videoFrame.release()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.