How to perform skin tone matching

后端 未结 2 1209
萌比男神i
萌比男神i 2021-01-14 05:35

( face )

( body )

Hi, i am new to image processing and openCV C/C++. I am wondering that is it possible to extract skin tone from the first image (face

2条回答
  •  忘掉有多难
    2021-01-14 06:15

    For finding skin you can use one of this formulas:

    1) With normilized RGB space:

    for(int i = 0; i < m_image->height; ++i)
    {
        for(int j = 0; j < m_image->width; ++j)
        {
            if (m_image->nChannels == 3)
            {
                int valueR = (reinterpret_cast(m_image->imageData + i * m_image->widthStep))[j * 3 + 2];
                int valueG = (reinterpret_cast(m_image->imageData + i * m_image->widthStep))[j * 3 + 1];
                int valueB = (reinterpret_cast(m_image->imageData + i * m_image->widthStep))[j * 3];
    
                float normR = static_cast(valueR) / static_cast(valueR + valueG + valueB);
                float normG = static_cast(valueG) / static_cast(valueR + valueG + valueB);
                float normB = static_cast(valueB) / static_cast(valueR + valueG + valueB);
    
                if ((normB / normG < 1.249) &&
                    (( normR + normG + normB ) / ( 3 * normR ) > 0.696 ) &&
                    ( 1/3.0 - normB/( normR + normG + normB ) > 0.014 ) &&
                    (normG/(3* (normR + normG + normB)) < 0.108 ))
                {
                  //pixel is skin
                }
            }
     }
    

    2) in RGB space:

    for(size_t i = 0; i < m_image->height; ++i)
    {
        for(size_t j = 0; j < m_image->width; ++j)
        {
            if (m_image->nChannels == 3)
            {
                int R = (reinterpret_cast(m_image->imageData + i * m_image->widthStep))[j * 3 + 2];
                int G = (reinterpret_cast(m_image->imageData + i * m_image->widthStep))[j * 3 + 1];
                int B = (reinterpret_cast(m_image->imageData + i * m_image->widthStep))[j * 3];
    
                if (( R > 95) && ( G > 40 ) && ( B > 20 ) &&
                    (std::max(R, std::max( G, B) ) - std::min(R, std::min(G, B) ) > 15) &&
                    (std::abs(R - G) > 15) && (R > G) && (R > B))
                {
                    //skin pixel
                }
    
            }
        }
    

    3) in YCrCb space:

    for(size_t i = 0; i < m_image->height; ++i)
    {
        for(size_t j = 0; j < m_image->width; ++j)
        {
            if (m_image->nChannels == 3)
            {
                int Cr = (reinterpret_cast(image->imageData + i * image->widthStep))[j * 3 + 2];
                int Cb = (reinterpret_cast(image->imageData + i * image->widthStep))[j * 3 + 1];
                int Y = (reinterpret_cast(image->imageData + i * image->widthStep))[j * 3];
    
                if (( Y > 80 ) && ( Cb > 85 ) && ( Cb < 135 ) &&
                    (Cr > 135) && (Cr < 180))
                {
                  //skin pixel
                }           
            }
        }
    }
    

提交回复
热议问题