【问题标题】:How to perform skin tone matching如何进行肤色匹配
【发布时间】:2013-06-20 07:40:53
【问题描述】:

(脸)

(身体)

嗨,我是图像处理和 openCV C/C++ 的新手。我想知道是否可以从第一张图像(面部)中提取肤色。然后应用于第二张图片(body)。

换句话说,用户上传他的面部图像,程序从该图像中提取肤色并将其应用于身体。

谢谢,

爱莎

【问题讨论】:

    标签: opencv image-processing skin


    【解决方案1】:

    这是一个很难解决的问题,尤其是考虑到颜色会因光照和反射而变化。我以前曾在图像中寻找皮肤,通常 YCbCr 颜色空间的 Cr(色度红色)分量在皮肤上非常突出。您或许可以利用此信息来查找皮肤区域。

    这里有几篇尝试使用颜色来定位人体皮肤的论文: 1.Interaction between hands and wearable cameras 2.Markerless inspection of augmented reality objects

    【讨论】:

      【解决方案2】:

      要查找皮肤,您可以使用以下公式之一:

      1) 使用归一化 RGB 空间:

      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<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 2];
                  int valueG = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 1];
                  int valueB = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3];
      
                  float normR = static_cast<float>(valueR) / static_cast<float>(valueR + valueG + valueB);
                  float normG = static_cast<float>(valueG) / static_cast<float>(valueR + valueG + valueB);
                  float normB = static_cast<float>(valueB) / static_cast<float>(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) 在 RGB 空间中:

      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<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 2];
                  int G = (reinterpret_cast<uchar*>(m_image->imageData + i * m_image->widthStep))[j * 3 + 1];
                  int B = (reinterpret_cast<uchar*>(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) 在 YCrCb 空间中:

      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<uchar*>(image->imageData + i * image->widthStep))[j * 3 + 2];
                  int Cb = (reinterpret_cast<uchar*>(image->imageData + i * image->widthStep))[j * 3 + 1];
                  int Y = (reinterpret_cast<uchar*>(image->imageData + i * image->widthStep))[j * 3];
      
                  if (( Y > 80 ) && ( Cb > 85 ) && ( Cb < 135 ) &&
                      (Cr > 135) && (Cr < 180))
                  {
                    //skin pixel
                  }           
              }
          }
      }
      

      【讨论】:

      • int main() { Mat ycrcb; Mat ycrcb1; Mat inputImage = imread("Skin image",1); Mat Image = imread("body image",1); cvtColor(inputImage,ycrcb,CV_BGR2YCrCb); cvtColor(Image,ycrcb1,CV_BGR2YCrCb); vector&lt;Mat&gt; channels; split(ycrcb,channels); vector&lt;Mat&gt; channels1; split(ycrcb1,channels1); channels1[0] = channels[0]; channels1[1] = channels[1]; channels1[2] = channels[2]; Mat result; merge(channels1,ycrcb1); cvtColor(ycrcb1,result,CV_YCrCb2BGR); imshow("new body image",result); return 0; }
      • 我已经从面部图像中提取了皮肤图像...在从中获取 YCrCb 值后,我正在尝试将这些值设置为身体图像...以便它可以匹配皮肤颜色..我不知道我错在哪里我的代码不起作用:(
      猜你喜欢
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 2014-01-16
      相关资源
      最近更新 更多