I have to capture skin colour independent of illumination. I used the following criteria(using hsv and rgb) but it ain't working:

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) && 
   // also skin color

It works in the morning when my skin is illuminated but by evening it does not work.

Any Help will be appreciated. Thanks in Advance. (PS -my skin ain't white.)

  • 2
    $\begingroup$ Could you provide sample pictures, and maybe describe desired output a little better? Do you want to "classify" image pixels in to non-skin and skin classes? Also, could you try and justify your criteria, maybe it is not so bad but it would help us in improving it if we understood how you came up with it. $\endgroup$
    – penelope
    Commented Jun 5, 2012 at 14:43
  • 2
    $\begingroup$ This might help (i.e. for removing effects of illumination first): dsp.stackexchange.com/a/459/35 $\endgroup$
    – datageist
    Commented Jun 5, 2012 at 15:13
  • $\begingroup$ these two criteria I just obtained from googling and yes I've to distinguish skin from non skin areas $\endgroup$ Commented Jun 5, 2012 at 16:16
  • $\begingroup$ I found this citeseerx.ist.psu.edu/viewdoc/… $\endgroup$ Commented Jun 6, 2012 at 3:06
  • 1
    $\begingroup$ here is an old question of mine, maybe it could help: dsp.stackexchange.com/questions/1625/… $\endgroup$
    – nkint
    Commented Jun 19, 2012 at 9:46

3 Answers 3


In my experience best method for this is converting it to Lab color space. L represents the light, and a and b are light independent. OpenCV supports Lab color scale conversion.

  • $\begingroup$ I've seen the same remark in the Face recognition handbook (Springer). Lab should be a better color space. $\endgroup$
    – sansuiso
    Commented Mar 7, 2013 at 7:40

try this:

''' 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')

For this special case, I recommend reading up on LAB Color model.

And in regard to the LAB Color model, read up on Delta E. The distance between 2 colors. More details about color space can be found here: http://www.codeproject.com/Articles/613798/Colorspaces-and-Conversions

I have never attempted the LAB color model via OpenCV as it's is a hassle to convert from RGB to LAB and back(requires an immediate step).

But I have explored Delta E on MatLab to great success. You have to select the skin first, draw a small ROI on the video/picture and the program will find all the exact same color tone as the skin you selected via the ROI.

Another option is also look into the texture. A short preview here: http://books.google.com.sg/books?id=bRlk_WjfITIC&pg=PA598&lpg=PA598&dq=skin+thresholding+from+texture&source=bl&ots=28fE0livyh&sig=8EeQTLFCc-JB979_-ccyrhDJlqA&hl=en&sa=X&ei=aAuFUsHhJoWJrQfpkoCgBg&ved=0CDUQ6AEwAQ#v=onepage&q=skin%20thresholding%20from%20texture&f=false

This is basically training a image database. Comment here if you need help to training the image database or conversion of ColorSpace. A little busy, so the answer is just suggestions that you can do. Cheers.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.