Reputation: 1833
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!
Upvotes: 2
Views: 3890
Reputation: 51
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
Upvotes: 5