Skin Detection and Segmentation in RGB Images


The Skin Detection and Segmentation is a process of finding skin-colored image regions from video frames or still pictures. Typically  this is a preprocessing step in the image analysis used to find significant regions such as body, hands, faces, etc. The skin detection and skin segmentation task is computationally efficient and is achieved in real-time. There are many tasks which require pixels classification and skin detection such as:

  • Face Detection
  • Hand Detection and Gesture Recognition
  • Image Nudity Measurements

Detecting skin colored pixels in image scenes seems like a trivial task, but it has proven quite challenging for many reasons. Skin detection process depends highly on image properties like illumination, background color and so on.


Skin Mask

The process of skin colors extraction is performed over colorful input image. An specific algorithm use color components to make proper decision is the current pixel fall down to skin color space or not. This results in a binary image called skin mask.

 

human hand

Original Human Hand Image

Human Hand Skin Mask

Human Hand Skin Mask

 


Appropriate Cr Space for Skin Color Detection

The RGB color space is one of the most widespread color representation consisting from: R – red, G – green and B- blur color components. These three color channels are highly correlated and contain luminance information along with the chromatic components. Because of this humans  perception is not linear to RGB color representation. There are significant studies about RGB to skin mask conversions. Below are some of the most widely used transformations for RGB skin color segmentation.

Direct RGB Transform

J. Kovac [2] proposed the following skin RGB color thresholds using direct RGB channel components:

  • At uniform day light illumination:

(R > 95), (G > 40), (B > 20),
max{R, G, B} − min{R, G, B} > 15,
|R − G| > 15, R>G, R>B

  • Skin tone threshold under flash light or daylight lateral illumination

(R > 220), (G > 210), (B > 170),
|R − G| ≤ 15, (R>B), (G>B)

 

Normalized RGB Transform

Researchers had proposed using normalized RGB values in order to minimize discrepancy caused by some color combinations. The RGB normalization is achieved using the following equations:

r = R / (R + G + B); g = G / (R + G + B); b = B / (R + G + B);

Gomez and Morales [3] determined that the following normalized rgb thresholds leads to best skin mask results:

r / g > 1.185, (r.b) / pow((r + g + b), 2) > 0.107, (r.g) / pow((r + g + b), 2) > 0.112

 

Skin Detection using YCbCr Color Space

Due to the fact that RGB to YCbCr color space conversion is straight forward it is commonly preferred. The  YCbCr  conversion is not computationally intensive compared to HSL/HSV transforms. The math used for conversion is the following:

`[[Y], [Cb], [Cr]]=[[16], [128], [128]] + [
[65.481, 128.553, 24.966],
[-37.797, -74.203, 112],
[112, -93.786, -18.214]][[R], [G], [B]]`

 

Using the math above, the resulting skin regions are separated by the following equations:

77≤Cb≤127 and 133≤Cr≤173

Our FivekoGFX implementation is using a slightly modified equation as proposed into [4]:

80≤Cb≤120 and 133≤Cr≤173

 


Skin Detection GPU Fragment Shader

The source code below is an OpenGL shader that performs a skin mask extraction on a YCbCr color image. The thr variable holds scaled threshold values which the GSLS uses to decide if the pixel in question is skin colored or not.


precision mediump float;
// our texture
uniform sampler2D u_image;
uniform vec2 u_textureSize;
vec4 thr = vec4(80.0/255.0, 120.0/255.0, 133.0/255.0, 173.0/255.0);
void main() {
	vec4 color = texture2D(u_image, gl_FragCoord.xy / u_textureSize);
	gl_FragColor = vec4(vec3(( (color[0] > thr[0]) && 
				(color[1] >= thr[0]) && (color[1] <= thr[1]) && 
				(color[2] >= thr[2]) && (color[2] <=thr[3])) ? 1.0 : 0.0), 
				color.a);
}

Image Nudity Detection

In many cases sensitive images providing naked bodies are not desired for web sites addressing general audience. Such cases require some sort of data filtering to prevent inappropriate content uploads. A general naive approach for nudity detection could be accomplished using following steps:

  1. Extract RGB pixel values from image in question
  2. Transform RGB components to YCbCr color space as described above
  3. Use the proposed Skin detection algorithm in order to segment skin regions
  4. Calculate skin to non-skin area ratio
  5. Validate skin ratio against predefined threshold and reject image if it exceeds

In order to increase algorithm robustness it is possible to include face detection step to the proposed sequence.


References

  1.  Human Computer Interaction Using Hand Gestures
  2. J. Kovac, P. Peer, and F. Solina, “Human skin colour clustering for face detection,” in in Proc. of International Conference on Computer as a Tool, 2003, pp. 144–148.
  3. Jones, M.J., Rehg, J.M: “Statistical color models with application to skin detection”, International Journal
    of Computer Vision (IJCV),46(1), 81-96(2002).
  4. Explicit Image Detection using YCbCr Space Color Model as Skin Detection