2

Got a question on how to use the EM algorithm in the latest OpenCV 2.4.2. I used to use the C version and it worked perfectly fine, but since the system upgrade it seems that the C API has been removed in OpenCV 2.4.2.

This is a simple case for the EM: suppose I have a list of radius that are considered to be from two kinds of balls and I want to estimate the mean/variance of these two types. In other words, it is a 1-D problem.

I tried to write the C++ version of EM using the new APIs, but haven't got it working yet.

int nsamples = radius_list.size();
int ncluster = 2;                 //we assume a bimodal model
Mat samples = Mat::zeros(nsamples, 1, CV_32FC1);

// init data
for (int i = 0; i < radius_list.size(); ++i) {
    int value = radius_list[i];
    samples.at<float>(i, 0) = value;
}
EM em_model = EM(ncluster, EM::COV_MAT_SPHERICAL);

if (!em_model.train(samples)) {
    cerr << "error training the EM model" << endl;
    exit(-1);
}

const Mat& means = em_model.get<Mat>("means");
int mean1 = means.at<float>(0, 0);
int mean2 = means.at<float>(1, 0);
cout << "mean1 = " << mean1 << ", mean2 = " << mean2 << endl;

const vector<Mat>& covs  = em_model.get<vector<Mat> >("covs");
int scale1 = covs[0].at<float>(0, 0);
int scale2 = covs[1].at<float>(0, 0);
cout << "scale1 = " << scale1 << ", scale2 = " << scale2 << endl;

The problem is: although the if() didn't complain, the retrieved mean and scale values are junk values, -2147483648 on my machine.

Please advise on how to modify the code to make it work. I'm still learning all sorts of C++ APIs in OpenCV.

Thank you all!

galactica
  • 1,753
  • 2
  • 26
  • 36
  • C API is not really removed. It now resides in opencv_legacy – Andrey Kamaev Jul 07 '12 at 07:59
  • Appreciate Andrey! After a while of testing/running, I got the C APIs back into the code and it seems to be working just fine! Although I can continue using the C APIs, I'm curious of moving to the C++ APIs as well. Any suggestions on the above code? – galactica Jul 07 '12 at 18:29
  • I advice you to get OpenCV source and study the implementation of old API. It is implemented as a wrapper for new `EM` class. Hope you'll find details missing in your code. – Andrey Kamaev Jul 07 '12 at 19:07
  • Please check http://stackoverflow.com/questions/19171607/expectation-maximization-get-covs-function-not-working-on-opencv-2-4-6-and-numbe, – antonio escudero Oct 04 '13 at 03:26

1 Answers1

5

Your doing implicit type conversions which distracts the compiler. Mean, weights and covariance matrices are not ints but doubles (you can check it by printing Mat.depth() result to the screen) so change all the lines from:

int mean1 = means.at<float>(0, 0);

like code to:

double mean1 = means.at<double>(0, 0);

Regards, Rafal

Rafal
  • 51
  • 1
  • 3