O OpenCV detecta a cor da pele invariável com alterações na iluminação

8

Eu tenho que capturar a cor da pele independentemente da iluminação. Eu usei os seguintes critérios (usando hsv e rgb), mas não está funcionando:

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 de manhã quando minha pele está iluminada, mas à noite não funciona.

Qualquer ajuda será apreciada. Desde já, obrigado. (PS - minha pele não é branca.)

Roney Island
fonte
2
Você poderia fornecer imagens de amostra e talvez descrever um pouco melhor a saída desejada? Deseja "classificar" os pixels da imagem nas classes não skin e skin ? Além disso, você poderia tentar justificar seus critérios, talvez não seja tão ruim, mas nos ajudaria a melhorá-lo se entendermos como você o criou.
Penelope
2
Isso pode ajudar (por exemplo, para remover os efeitos da iluminação primeiro): dsp.stackexchange.com/a/459/35
datageist
estes dois critérios eu obtidos a partir pesquisando e sim eu tenho que distinguir a pele de áreas não pele
Roney Ilha
Eu encontrei este citeseerx.ist.psu.edu/viewdoc/…
Roney Island
11
aqui é uma velha questão da mina, talvez ele poderia ajudar: dsp.stackexchange.com/questions/1625/...
nkint

Respostas:

4

Na minha experiência, o melhor método para isso é convertê-lo no espaço de cores do laboratório. L representa a luz, e a e b são independentes da luz. O OpenCV suporta conversão de escala de cores do laboratório.

Vladimir Perković
fonte
Eu vi a mesma observação no manual de reconhecimento de rosto (Springer). O laboratório deve ter um espaço de cores melhor.
Sansuiso
2

Para este caso especial, recomendo a leitura do modelo LAB Color.

E, em relação ao modelo LAB Color, leia o Delta E. A distância entre duas cores. Mais detalhes sobre o espaço de cores podem ser encontrados aqui: http://www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

Eu nunca tentei o modelo de cores LAB via OpenCV, pois é um incômodo converter de RGB para LAB e vice-versa (requer uma etapa imediata).

Mas eu explorei o Delta E no MatLab com grande sucesso. É necessário selecionar a capa primeiro, desenhar um pequeno ROI no vídeo / imagem e o programa encontrará exatamente o mesmo tom de cor da capa que você selecionou através do ROI.

Outra opção também é olhar para a textura. Uma breve visualização aqui: http://books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFCc-JBf79&hl=pt_BR = 0CDUQ6AEwAQ # v = uma página & q = skin% 20thresholding% 20from% 20texture & f = false

Isso é basicamente o treinamento de um banco de dados de imagens. Comente aqui se precisar de ajuda para treinar o banco de dados de imagens ou a conversão do ColorSpace. Um pouco ocupado, então a resposta são apenas sugestões que você pode fazer. Felicidades.

rockinfresh
fonte
1

tente isto:

''' 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()
samkhan13
fonte