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 digital image analysis to find significant regions such as body, hands, faces, etc.

How to detect and segment skin color?

Similar to Watershed segmentation, the purpose of the algorithm is to obtain accurate zones for the specified criterion.

Typically, the skin separation method starts with an RGB image and results in a binary mask .

The skin detection and skin segmentation task is computationally efficient and achieved in real-time. There are many tasks that require pixel 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.

How to extract Skin Mask from images and video

This algorithm converts from a colorful image to a binary skin mask. We 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.

Appropriate Color Space for Skin Segmentation

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. Therefore, people do not linearly perceive the representation of RGB color space.

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:

$\displaystyle{\left[\begin{matrix}{Y}\\{C}{b}\\{C}{r}\end{matrix}\right]}={\left[\begin{matrix}{0.0625}\\{0.5}\\{0.5}\end{matrix}\right]}+{\left[\begin{matrix}{0.257}&{0.504}&{0.098}\\-{0.148}&-{0.291}&{0.439}\\{0.439}&-{0.368}&-{0.071}\end{matrix}\right]}{\left[\begin{matrix}{R}\\{G}\\{B}\end{matrix}\right]}$
RGB to YCbCr color conversion

We use the new YCbCr color space to separate the skin regions by the below ranges:

77≤Cb≤127 and 133≤Cr≤173

Our image analysis test environment uses a slightly modified equation as suggested by [4]:

80≤Cb≤120 and 133≤Cr≤173

Skin Detection Source Code

The source code below represents a GPU implementation for skin detection.

To extract the skin mask from the input image, we transform from RGB to YCbCr color space. The thr variable holds scaled threshold values that 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

Many websites targeting a wide audience are reluctant to display naked body images. Such cases require some sort of data filtering to prevent inappropriate content uploads.

The following steps show a general naive approach for nudity detection:

  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 it

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


computer-vision-tutorials-fivekogfx

See it Online!

SKIN DETECTION DEMO


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

Related articles