OpenCV rileva il colore della pelle invariante con i cambiamenti di illuminazione


8

Devo catturare il colore della pelle indipendentemente dall'illuminazione. Ho usato i seguenti criteri (usando hsv e rgb) ma non funziona:

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
}

Funziona al mattino quando la mia pelle è illuminata ma la sera non funziona.

Qualsiasi aiuto sarà apprezzato. Grazie in anticipo. (PS: la mia pelle non è bianca.)


2
Potresti fornire immagini di esempio e forse descrivere un po 'meglio l'output desiderato? Vuoi "classificare" i pixel dell'immagine in classi non skin e skin ? Inoltre, potresti provare a giustificare i tuoi criteri, forse non è poi così male ma ci aiuterebbe a migliorarlo se capissimo come ti sei inventato.
penelope,

2
Questo potrebbe aiutare (cioè per rimuovere prima gli effetti dell'illuminazione): dsp.stackexchange.com/a/459/35
datageist

questi due criteri che ho appena ottenuto da Google e sì, devo distinguere la pelle dalle aree non cutanee
Roney Island,


1
ecco una mia vecchia domanda, forse potrebbe aiutare: dsp.stackexchange.com/questions/1625/…
nkint

Risposte:


4

Nella mia esperienza, il metodo migliore per farlo è convertirlo nello spazio colore Lab. L rappresenta la luce e aeb sono indipendenti dalla luce. OpenCV supporta la conversione della scala di colori Lab.


Ho visto la stessa osservazione nel manuale di riconoscimento facciale (Springer). Lab dovrebbe essere uno spazio colore migliore.
Sansuiso,

2

Per questo caso speciale, consiglio di leggere sul modello LAB Color.

E per quanto riguarda il modello LAB Color, leggi su Delta E. La distanza tra 2 colori. Maggiori dettagli sullo spazio colore possono essere trovati qui: http://www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

Non ho mai provato il modello di colore LAB tramite OpenCV in quanto è una seccatura convertire da RGB a LAB e viceversa (richiede un passaggio immediato).

Ma ho esplorato Delta E su MatLab con grande successo. Devi prima selezionare la skin, disegnare un piccolo ROI sul video / immagine e il programma troverà esattamente la stessa tonalità di colore della skin selezionata tramite il ROI.

Un'altra opzione è anche esaminare la trama. Una breve anteprima qui: http://books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFCc-JQ&q = 0CDUQ6AEwAQ # v = onepage & q = pelle% 20thresholding% 20from% 20texture & f = false

Questo sta fondamentalmente addestrando un database di immagini. Commenta qui se hai bisogno di aiuto per addestrare il database di immagini o la conversione di ColorSpace. Un po 'occupato, quindi la risposta è solo suggerimenti che puoi fare. Saluti.


1

prova questo:

''' 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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.