【问题标题】:Got different EM::predict() results after EM::read() saved model in OpenCVEM::read() 在 OpenCV 中保存模型后得到不同的 EM::predict() 结果
【发布时间】:2014-06-22 13:15:16
【问题描述】:

我是 OpenCV 和 C++ 的新手,我正在尝试在 OpenCV 中使用高斯混合模型构建分类器。我弄清楚了它是如何工作的,并让它发挥了作用……也许吧。我现在得到了这样的东西:

如果我在模型被训练和保存之后对训练样本进行分类,我得到了我想要的结果。但是当我使用 read() 重新分类我的训练数据时,其中一个集群丢失了,这意味着我从同一个 GMM 模型得到了不同的集群结果。我现在不明白,因为我想要的集群已经消失了,我无法再次重现分类,直到我使用相同的数据重新训练模型。我在运行时检查了代码,并且 Vec2d 中的 result 值从未分配过 predict() 返回的值为 1(我设置了 3 个集群)。

也许有错误或我做错了什么?

附言我在 VS2013 中使用的是 2.4.8

我的程序是这样的:

火车部分

void GaussianMixtureModel::buildGMM(InputArray _src){
    //use source to train GMM and save the model

    Mat samples, input = _src.getMat();    
    createSamples(input, samples);
    bool status = em_model.train(samples);

    saveModel();
}

保存/加载模型

FileStorage fs(filename, FileStorage::READ);
if (fs.isOpened()) // if we have file with parameters, read them
{
    const FileNode& fn = fs["StatModel.EM"];
    em_model.read(fn);
    fs.release();
}

FileStorage fs_save(filename, FileStorage::WRITE);
if (fs_save.isOpened()) // if we have file with parameters, read them
{
    em_model.write(fs_save);
    fs_save.release();
}

预测部分

vector<Mat> GaussianMixtureModel::classify(Mat input){
/// samples is a matrix of channels x N elements, each row is a set of feature
Mat samples;
createSamples(input, samples);
    for (int k = 0; k < clusterN; k++){
        masks[k] = Mat::zeros(input.size(), CV_8UC1);
    }
int idx = 0;
for (int i = 0; i < input.rows; i++){
    for (int j = 0; j < input.cols; j++){
        //process the predicted probability
        Mat probs(1, clusterN, CV_64FC1);
        Vec2d response = em_model.predict(samples.row(idx++), probs);
        int result = cvRound(response[1]);
        for (int k = 0; k < clusterN; k++){
                            if (result == k){
                // change to the k-th class's picture
                masks[k].at<uchar>(i, j) = 255;
            }
                    ...
                    // something else
                    }
             }
       }
}

【问题讨论】:

    标签: opencv expectation-maximization


    【解决方案1】:

    我想我的回答为时已晚,但由于我遇到了同样的问题,我找到的解决方案可能对其他人有用。

    通过分析源代码,我注意到在 EM::COV_MAT_DIAGONAL 的情况下,协方差矩阵的特征值(源代码中的 covsEigenValues)是在加载保存的数据后通过 SVD 获得的。 然而,SVD 计算奇异值(在我们的例子中为特征值)并以升序存储。 为了防止这种情况,我只是直接提取 covsEigenValues 中加载的协方差矩阵的对角元素以保持良好的顺序。

    【讨论】:

      猜你喜欢
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 2011-06-29
      • 2017-01-04
      • 2018-01-16
      • 2010-12-30
      • 2012-05-15
      相关资源
      最近更新 更多