肤色检测算法--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空间

posted on 2014-02-27 14:33  leezivin  阅读(1731)  评论(0编辑  收藏  举报

导航