Updated by Kirill Kornyakov almost 13 years ago
Currently it appears impossible to use CvEM to do classification eg. foreground/background segmentation based on colours. The predict function returns an integer index indicating which of the cluster has the highest score, but not the actual probability of a sample belonging to the CvEM model. The following simple change makes this possible.
em.cpp at line 288 to get rid of the normalisation:
<pre>
//CV_CALL( cvConvertScale( &expo, _probs, 1./cvSum( &expo ).valr0 ));
CV_CALL( cvCopy(&expo, _probs) );
With the changes made, one can get the probability of a sample for classification as follows:
sample.data.flr0 = (float)r;
sample.data.flr1 = (float)g;
sample.data.flr2 = (float)b;
em_model_FG.predict(&sample, probFG);
em_model_BG.predict(&sample, probBG);
double scoreFG = 0;
double scoreBG = 0;
// For GMM we use addition, not multiplication
for(unsigned int k=0; k < GMM_FG; k++)
scoreFG += probFG->data.db[k];
for(unsigned int k=0; k < GMM_BG; k++)
scoreBG += probBG->data.db[k];
if(scoreFG > scoreBG)
return 1;
else
return 0;
</pre>
Or alternatively, make predict() return the probability by default.
em.cpp at line 288 to get rid of the normalisation:
<pre>
//CV_CALL( cvConvertScale( &expo, _probs, 1./cvSum( &expo ).valr0 ));
CV_CALL( cvCopy(&expo, _probs) );
With the changes made, one can get the probability of a sample for classification as follows:
sample.data.flr0 = (float)r;
sample.data.flr1 = (float)g;
sample.data.flr2 = (float)b;
em_model_FG.predict(&sample, probFG);
em_model_BG.predict(&sample, probBG);
double scoreFG = 0;
double scoreBG = 0;
// For GMM we use addition, not multiplication
for(unsigned int k=0; k < GMM_FG; k++)
scoreFG += probFG->data.db[k];
for(unsigned int k=0; k < GMM_BG; k++)
scoreBG += probBG->data.db[k];
if(scoreFG > scoreBG)
return 1;
else
return 0;
</pre>
Or alternatively, make predict() return the probability by default.