肤色检测算法--color space
肤色检测在很多地方都会应用到,这里就不详细展开说了。本文主要说说肤色检测的算法,目前肤色检测的方法主要有两种,一种是根据颜色空间转换的方法,另外一种是根据纹理来检测肤色。本文将详细描述第一种方法。
不多说了,直接上代码。
1,RGB颜色空间。
int skinDeteRGB(Image *destImage, unsigned char *result) { if(NULL == destImage || result == NULL) return 0; int i, j; unchar *pixels = NULL; int width = destImage->nWidth; int height = destImage->nHeight; int Max, Min; unsigned char *ptr = result; int table[256]; for(i = 0; i< 256; ++i) table[i] = 0; for (j = 0; j < height; j++) { pixels = getPixelAddress(destImage, 0, j); for (i = 0; i < width; i++) { int Red = pixels[0]; int Green = pixels[1]; int Blue = pixels[2]; *(ptr + j*width + i) = 0; if (Red > 95 && Green > 40 && Blue > 20 && Red > Blue && Red > Green && abs(Red - Green) > 15) { if (Blue >= Green) { Max = Blue; Min = Green; } else { Max = Green; Min = Blue; } if (Red > Max) Max = Red; else if (Red < Min) Min = Red; if (Max - Min > 15) { *(ptr + j*width + i) = 255; table[Red]++; } } pixels += 4; } } return 1; }
2,在YCbCr空间,使用Otsu阀值来分离肤色和非肤色的区域,核心代码如下:
int skinDeteYCC(Image *destImage) { if(NULL == destImage) return 0; int width = getWidth(destImage); int height = getHeight(destImage); unsigned char *pixels = NULL; unsigned char *cpixels = NULL; int i,j; int Y, Cb, Cr; int average = 0; Image *crImage = (Image *)malloc(sizeof(Image)); cloneImage(crImage, destImage); for(j = 0; j < height; ++j) { pixels = getPixelAddress(destImage, 0, j); cpixels = getPixelAddress(crImage, 0, j); for(i = 0; i < width; ++i) { Cr = pixels[0] * 0.439215 + pixels[1] * (-0.367789) + pixels[2] * (-0.071426)+ 128;
cpixels[0] = cpixels[1] = cpixels[2] = Cr; pixels += 4; cpixels += 4; } } int otsu = getThresholdOtsu(crImage); for(j = 0; j < height; ++j) { pixels = getPixelAddress(destImage, 0, j); cpixels = getPixelAddress(crImage, 0, j); for(i = 0; i < width; ++i) { if(cpixels[0] == cpixels[1] && cpixels[1] == cpixels[2] && cpixels[0] < otsu) { pixels[0] = pixels[1] = pixels[2] = pixels[3] = 0; } pixels += 4; cpixels += 4; } } destroyImage(crImage); free(crImage); return 1; }
下面是测试一副图的效果:
原图 RGB空间 YCbCr空间