Question

I am using the following algorithm to detect skin color, but its not working real well in different lighting conditions. Can anybody offer any advice how to improve it or suggest a better approach

R > 95 AND G > 40 AND B > 20 AND
max{R, G, B} – min{R, G, B} >15 AND
|R – G| > 15 AND
R > G AND R > B
OR
R > 220 AND G > 210 AND B > 170 AND
|R – G| <= 15 AND
R > B AND G > B

http://softexpert.wordpress.com/2007/10/17/skin-color-detection/

Cheers

Was it helpful?

Solution

Your given algorithm is simple colour based thresholding. This will only work for a very basic set of conditions. For a few pictures it may give really good results but as a general detector it will give poor results.

Your first line of attack should be to switch to a different colour model that is invariant to illumination. In fact, the link that you give explicitly says this! For example, HSI. Personally, I would prefer to do something with L*a*b* but implementation of conversion from RGB would be more difficult.

You should look at adding some additional prior terms, for example, isolated pixels cannot be skin.

OTHER TIPS

There are a lot of methods for skin colour modelling, each has its pros and cons.

Pick one based on your purposes. Look at these surveys:

V. Vezhnevets, V. Sazonov, A. Andreeva. A survey on pixel-based skin color detection techniques. Proc. Graphicon, 2003

P. Kakumanu, S. Makrogiannis, N. Bourbakis. A survey of skin-color modeling and detection methods. Pattern recognition, 2007

I've used chrominance components to quickly get skin-toned regions of an image.

It's not perfect, but it's alright if all you want is a quick and dirty approach.

The paper is called "Face segmentation using skin-color map in videophone applications" by Douglas Chai. It's a fairly old approach (1999). Unfortunately, the paper itself is behind a pay-wall, but the approach is fairly simple:

  • Detect areas with potential skin tones by using a range for Cb and Cr
  • Morphological operations to clean up image
  • Using standard deviation, further separation of background (low) and foreground (high)
  • Some more morphological operations to further clean up the image
  • Contour reconstruction (smooth curves) to produce the result

If you are using RGB, you will have problems with lighting(luminance). Best way to deal with skin color detection is YCbCr composition. Y for luminance Cb and Cr for chrominance. Each are expressed as weighed expression of RGB colors. But you use only Cb and Cr to identify skin colors. Y is discarded since you don't want the luminace in your analysis. So use YCbCr instead of RGB. Hope I helped!

See my answer to robust hand detection here where I recommended a method using color histogram built using just the hue and saturation channels of an image originally from Gary Bradski (OpenCV's creator)'s paper on face tracking. It includes an overview of the method as well as links to sample code on how to detect skin region.

The method is simple yet fairly robust to noise and lighting variations as well as being able to detect different skin tones. No machine learning needed :).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top