OpenCV 期望最大化

Posted

技术标签:

【中文标题】OpenCV 期望最大化【英文标题】:OpenCV Expectation Maximization 【发布时间】:2013-05-23 06:50:12 【问题描述】:

我正在尝试在 OpenCV 2.4.5 上使用 EM 进行背景和前景图像分离。但是,与以前版本的 C 类不同,c++ 对我来说非常混乱,并且由于缺乏文档(从我的观点来看),一些例程相当混乱。

我写了下面的代码,但它似乎不起作用。它给出了错误,我非常努力地调试但仍然无法正常工作。

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;

基本上,我将图像转换为 CV_64F 类型的浮点数并将其传递到训练例程中。也许我认为我错了,我可以就我的错误获得帮助。谢谢

【问题讨论】:

首先添加你得到的错误。 【参考方案1】:

你正在混合你的浮点类型。

如果需要双精度,请将Vec3f 更改为Vec3d

否则

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

应该是

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

【讨论】:

请注意,根据文档,EM 例程在内部将 Mat 转换为 CV_64F,如果它还不是 CV_64F。因此,Vec3fVec3d 的更改应该是大多数情况下的首选解决方案(尤其是性能方面)。 --- 来自 EM::train() 关于第一个参数的文档: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.

以上是关于OpenCV 期望最大化的主要内容,如果未能解决你的问题,请参考以下文章

opencv中机器学习常用算法简述

OpenCV4.1.1版本的EM算法实现

机器学习的优化目标期望最大化(Expectation-Maximum, EM)算法期望最大化(EM)和梯度下降对比

Expectation Maximization-EM(期望最大化)-算法以及源码

期望最大化问题 - 如何在数据中找到最佳高斯数

期望最大化抛硬币示例