2013-06-25 1 views
3

피부 검색 알고리즘을 this article에 따라 수행하고 있습니다. 21 페이지에는 Gaussian Skin과 Non-Skin Color Model의 두 가지 모델이 있습니다.가우시안 혼합 모델을 이용한 피부 검출

피부 감지를위한 첫 번째 모델은 exellent로 작동합니다.

1) orginal 한 이미지 :

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; 
} 

을하고 있어요 무엇 : 여기 691,363,210

내 코드? 어쩌면 나는 tre 기사의 의미를 오해 할까? 아니면 코드에서 수식이 잘못 번역 되었습니까?

미리 감사드립니다.

+0

당신이 뭘 잘못하고 있는지 = 당신은 피부 감지를하고 있지만 누드 탐지기라고 부릅니다. 미안, 농담. – ondrejdee

답변

2

사실, 비 피부 모델에서는 비 피부 영역을 255로 정확하게 식별하고 피부 영역을 0으로 정확하게 식별합니다. 매개 변수 probValue을 조정하여 (작은 비 피부 영역)

GMM은 피부 감지에 효과적인 방법이 아니며 탐지 된 영역이 조각화되지 않도록 정규화 매개 변수로 일부 강도 정보를 사용할 수 있습니다.

관련 문제