Ask Your Question

using EM of opencv, same training samples, but different results

asked 2013-07-29 03:06:19 -0600

peter307 gravatar image

updated 2013-07-29 22:35:13 -0600

Sorry for the mistake!! I have update this post? Can you try this and show me the results running on your machine??

Hi everyone,

I'm using the EM module of opencv(tried 2.4.2 and 2.4.3). I wants to try my samples(676*64) which is generated by SIFT+PCA by EM. but I have tried to use the same samples to train the EM to get the Gaussian mixture model. But the results are different.

here is a test code.

cv::Mat samples(50,2,CV_32FC1);
samples = samples.reshape(2,0);

int N=9, n1 = sqrt(9.0);
for(int i=0; i<N; ++i)
    cv::Mat subSamples = samples.rowRange(i*50/N, (i+1)*50/N );
    cv::Scalar mean((i%3 +1)*256/4, (i/3+1)*256/4);
    cv::Scalar var(30,30);
    cv::randn(subSamples, mean, var);
samples = samples.reshape(1,0);

samples.convertTo(samples, CV_64FC1);

for(int j=0; j<samples.rows; ++j){
    for(int i=0; i<samples.cols; ++i)
        std::cout<<<double>(j, i)<<" ";

CvEM m_emModel1;
CvEMParams params1;
cv::Mat labels1;

params1.covs      = NULL;
params1.means     = NULL;
params1.weights   = NULL;
params1.probs     = NULL;
params1.nclusters = 10;
params1.cov_mat_type       = CvEM::COV_MAT_SPHERICAL;
params1.start_step         = CvEM::START_AUTO_STEP;
params1.term_crit.type     = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
m_emModel1.train(samples, cv::Mat(), params1, &labels1);

for(int j=0; j<10; ++j){
    for(int i=0; i<2; ++i)
        std::cout<<m_emModel1.getMeans().at<double>(j, i)<<" ";

for(int j=0; j<10; ++j)
    std::cout<<m_emModel1.getWeights().at<double>(j)<<" ";

CvEM m_emModel;
CvEMParams params;
cv::Mat labels;

params.covs      = NULL;
params.means     = NULL;
params.weights   = NULL;
params.probs     = NULL;
params.nclusters = 10;
params.cov_mat_type       = CvEM::COV_MAT_SPHERICAL;
params.start_step         = CvEM::START_AUTO_STEP;
params.term_crit.type     = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
m_emModel.train(samples, cv::Mat(), params, &labels);

for(int j=0; j<10; ++j){
    for(int i=0; i<2; ++i)
        std::cout<<m_emModel.getMeans().at<double>(j, i)<<" ";

for(int j=0; j<10; ++j)
    std::cout<<m_emModel.getWeights().at<double>(j)<<" ";

here is a result: image description

I really hope your replys, thanks your reading.

edit retag flag offensive close merge delete



You train your GMM with two different models and get two different results. So, what exactly is your question?

Guanta gravatar imageGuanta ( 2013-07-29 05:16:21 -0600 )edit

And your parameters are different (epsilon and start_step). By the way, not related, but I suggest you used the C++ interface (

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2013-07-29 05:57:07 -0600 )edit

hi Guanta and Mathieu, I have update the code. This time all the parameters are the same. But I still get different results?? any suggestion?

peter307 gravatar imagepeter307 ( 2013-07-29 22:39:17 -0600 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2013-07-30 03:06:16 -0600

Guanta gravatar image

The reason why you get different results is hidden in one of the parameters you use: CvEM::START_AUTO_STEP . Thereby the k-means algorithm is used to estimate the initial parameters. Since k-means is initialized with random initial centers (KMEANS_PP_CENTERS) it results in different outcomes of parameters and thus different initial parameters for the EM-algorithm. If you use a large amount of data, I guess the effect will be reduced. However, if you don't want this effect at all, you have to initialize your EM-algorithm by hand and then use either CvEM::START_E_STEP or CvEM::START_M_STEP.

edit flag offensive delete link more


You right. But seems that the same result provides only START_M_STEP. START_E_STEP returns diff result as START_AUTO_STEP.

oktay gravatar imageoktay ( 2018-03-22 10:00:21 -0600 )edit

Question Tools

1 follower


Asked: 2013-07-29 03:06:19 -0600

Seen: 759 times

Last updated: Jul 30 '13