Rilevazione della pelle con modelli di miscela gaussiana

Sto facendo l’algoritmo di rilevamento della pelle secondo questo articolo . Ci sono due modelli a pagina 21: Mixture of Gaussian Skin e Non-skin Color Model.

Il primo modello per il rilevamento della pelle funziona eccellente. Ci sono esempi:

1) Immagine originale:

inserisci la descrizione dell'immagine qui

2) Maschera per la pelle

inserisci la descrizione dell'immagine qui

Ma il modello non a pelle dà risultati sbagliati:

inserisci la descrizione dell'immagine qui

Ecco il mio codice:

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 height; ++i) { for(int j = 0; j width; ++j) { if (m_image.get()->nChannels == 3) { x[0] = (reinterpret_cast(m_image.get()->imageData + i * m_image.get()->widthStep))[j * 3 + 2]; x[1] = (reinterpret_cast(m_image.get()->imageData + i * m_image.get()->widthStep))[j * 3 + 1]; x[2] = (reinterpret_cast(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(mask.get()->imageData + i * mask.get()->widthStep))[j] = 0; } else { (reinterpret_cast(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; } 

Cosa sto facendo di sbagliato? Forse ho frainteso il significato di tre articoli? Oppure ho tradotto la formula sbagliata nel codice?

Grazie in anticipo!

Infatti, sembra non esserci nulla di sbagliato con i risultati, il modello non-skin identifica correttamente le regioni non cutanee come 255 e le regioni cutanee come 0. Potresti semplicemente aver bisogno di sintonizzare il parametro probValue su un valore inferiore per sbarazzarti di alcuni falsi negativi (piccole regioni non cutanee)

La GMM potrebbe non essere un approccio efficace per il rilevamento della pelle e si potrebbe impiegare alcune informazioni sull’intensità del bordo come parametro di regolarizzazione in modo che le regioni rilevate non siano frammentate.