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

Similar to Watershed segmentation, the purpose of the algorithm is to obtain accurate zones for the specified criterion. Our skin separation method starts from an RGB image and we get a binary mask as a result.

The skin detection and skin segmentation task is computationally efficient and 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

This algorithm makes conversion from colorful image to 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.

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]]`

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

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

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.


  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