3

I am trying to use EM on OpenCV 2.4.5 for background and foreground image separation. However, unlike the previous version of C class, the c++ is very confusing to me and several routines are rather confusing due to lack of documentation (from my point..)

I wrote the following code, but it seems not to work. It gives error and I tried very hard to debug but still not working.

Mat image;
image = imread("rose.jpg",1);

Mat _m(image.rows, image.cols, CV_32FC3);
Mat _f(image.rows, image.cols, CV_8UC3);
Mat _b(image.rows, image.cols, CV_8UC3);

Mat sample(image.rows * image.cols, 3, CV_32FC1);

Mat float_image;
image.convertTo(float_image,CV_64F);

Mat background_ = Mat(image.rows * image.cols, 3, CV_64F);

int counter = 0;
//Converting from Float image to Column vector
for (int j = 0; j < image.rows; j++)
{
    Vec3f* row = float_image.ptr<Vec3f > (j);

    for (int i = 0; i < image.cols; i++)
    {
        sample.at<Vec3f> (counter++, 0) = row[i];
    }
}

//sample.reshape(1,image.rows * image.cols);
cout<<"Training"<<endl;
EM params = EM(2);
params.train(sample);
    Mat _means = params.get<Mat>("means");
Mat _weights = params.get<Mat> ("weights");
cout<<"Finished Training"<<endl;

Basically, I am converting the image to float of type CV_64F and passing it into the training routine. Perhaps I think i am wrong, can i get help on my error. Thank you

Alex Riley
  • 169,130
  • 45
  • 262
  • 238
kcc__
  • 1,638
  • 4
  • 30
  • 59

1 Answers1

3

You are mixing your float types.

If you need double precision, change Vec3f to Vec3d.

Otherwise

image.convertTo(float_image,CV_64F);
Mat background_ = Mat(image.rows * image.cols, 3, CV_64F);

should be

image.convertTo(float_image,CV_32F);
Mat background_ = Mat(image.rows * image.cols, 3, CV_32F);
Bull
  • 11,771
  • 9
  • 42
  • 53
  • Note that, according to the documentation, the EM routines convert the Mat to CV_64F internally, if it is not already CV_64F. Hence, the `Vec3f`to `Vec3d` change should be the preferred solution in most situations (especially performance wise). --- from docs of EM::train() about the first parameter: `samples – Samples from which the Gaussian mixture model will be estimated. It should be a one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type it will be converted to the inner matrix of such type for the further computing.` – SDwarfs Feb 28 '19 at 16:25