2013-06-25 60 views
3

我正在根据this article进行皮肤检测算法。第21页有两个模型:高斯肤色和非肤色肤色模型的混合。使用高斯混合模型的皮肤检测

皮肤检测的第一个模型作品非常优秀。 有例子:

1)原单的图像:

enter image description here

2)皮肤的面膜

enter image description here

但非皮肤模型给出了错误的结果:

enter image description here

这里是我的代码:

ipl_image_wrapper NudityDetector::filterPixelsWithGMM(const float covarinceMatrix[][3], const float meanMatrix[][3], const float weightVector[], const float probValue) const 
{ 
    ipl_image_wrapper mask = cvCreateImage(cvGetSize(m_image.get()), IPL_DEPTH_8U, 1); 

    double probability = 0.0; 
    float x[3] = { 0, 0, 0}; 

    for(int i = 0; i < m_image.get()->height; ++i) 
    { 
     for(int j = 0; j < m_image.get()->width; ++j) 
     { 
      if (m_image.get()->nChannels == 3) 
      { 
       x[0] = (reinterpret_cast<uchar*>(m_image.get()->imageData + i * m_image.get()->widthStep))[j * 3 + 2]; 
       x[1] = (reinterpret_cast<uchar*>(m_image.get()->imageData + i * m_image.get()->widthStep))[j * 3 + 1]; 
       x[2] = (reinterpret_cast<uchar*>(m_image.get()->imageData + i * m_image.get()->widthStep))[j * 3]; 

       double cov_det = 0.0; 
       double power = 0.0; 

       double A1 = 0.0; 
       double A2 = 0.0; 
       double A3 = 0.0; 

       probability = 0; 

       for (int k = 0; k < 16; ++k) 
       { 
        cov_det = covarinceMatrix[k][0] * covarinceMatrix[k][1] * covarinceMatrix[k][2]; 

        A1 = covarinceMatrix[k][1] * covarinceMatrix[k][2]; 
        A2 = covarinceMatrix[k][0] * covarinceMatrix[k][2]; 
        A3 = covarinceMatrix[k][0] * covarinceMatrix[k][1]; 

        power =(std::pow((x[0] - meanMatrix[k][0]), 2) * A1 + 
          std::pow((x[1] - meanMatrix[k][1]), 2) * A2 + 
          std::pow((x[2] - meanMatrix[k][2]), 2) * A3)/(2 * cov_det); 

        probability += 100 * weightVector[k] *std::exp(-power)/(std::pow(2 * M_PI, 3/2) * std::pow(cov_det, 1/2)); 
       } 

       if (probability < probValue) 
       { 
        (reinterpret_cast<uchar*>(mask.get()->imageData + i * mask.get()->widthStep))[j] = 0; 
       } 
       else 
       { 
        (reinterpret_cast<uchar*>(mask.get()->imageData + i * mask.get()->widthStep))[j] = 255; 
       } 
      } 
     } 
    } 

    cvDilate(mask.get(), mask.get(), NULL, 2); 
    cvErode(mask.get(), mask.get(), NULL, 1); 

    return mask; 
} 

ipl_image_wrapper NudityDetector::detectSkinWithGMM(const float probValue) const 
{ 
    //matrices are from article 
    ipl_image_wrapper mask = filterPixelsWithGMM(COVARIANCE_SKIN_MATRIX, MEAN_SKIN_MATRIX, SKIN_WEIGHT_VECTOR, probValue); 

    return mask; 
} 

ipl_image_wrapper NudityDetector::detectNonSkinWithGMM(const float probValue) const 
{ 
    //matrices are from article 
    ipl_image_wrapper mask = filterPixelsWithGMM(COVARIANCE_NON_SKIN_MATRIX, MEAN_NON_SKIN_MATRIX, NON_SKIN_WEIGHT_VECTOR, probValue); 

    return mask; 
} 

我做错了吗?也许我误解了tre文章的含义?或者我在代码中翻译了错误的公式?

预先感谢您!

+0

你在做什么错=你正在做皮肤检测,但称之为裸露检测器。对不起,开玩笑。 – ondrejdee

回答

2

实际上,结果似乎没有错,非皮肤模型正确地将非皮肤区域标识为255,将皮肤区域标识为0.您可能只需将参数probValue调整为较低值即可摆脱的一些假阴性(小的非皮肤区域)

GMM可能不是一种有效的皮肤检测方法,您可以使用一些边缘强度信息作为正则化参数,以便检测到的区域不会被分割。