您的位置:首页 > 运维架构

用opencv中的CvEM做GMM的训练

2013-10-22 10:17 99 查看
GMM(“Gaussian Mixture Model”)这个东西,来源于Adaptive
background mixture models for real-time tracking。事实上就是把一系列的数据的分布用几个加权的高斯去拟合。

这东西我能想到的有两个用法:其中一个就是opencv官网上给出来的例子,对于一系列的点,训练一个GMM。对于每个点检查对它来说属于哪个Gaussian的成分更高,就属于哪一类。就这么实现了聚类。另一个用法是用来给色彩或者别的统计信息建立一个模型。举个例子,假设我知道一张训练图片的前景的mask,那么就可以把它的前景中的所有像素的像素值作为训练的sample,给前景训练一个GMM模型。接着对于其他图像的每个像素都可以根据这个GMM来预测属于前景的一个概率,对于背景也是同样的做法。类似的做法出现在了很多cv的paper上。

虽然这东西理解起来很简单,但是去拟合训练数据一般是要用到EM算法的,这货写起来也很麻烦。所以在opencv有了CvEM之后还是很好用的(说起来这货应该叫CvGMM吧,要不用EM算法的也不止GMM一个啊)。不过需要注意到的是现在CvEM已经被移动到了legacy里去了,说明很可能过几版就要被删掉了。

opencv中的CvEM这个类主要有以下几个比较重要的方法:

boo CvEM::train(const Mat& samples, const Mat& sampleIdx=Mat(), CvEMParams params=CvEMParams(), Mat* labels=0 )


训练GMM。其中第一个参数是训练的sample,类型是Mat,一行一个sample。假设我们有100个像素,每个像素都是RGB的色彩。那么训练的samples肯定就是一个100行三列的Mat。第一行第一列就是第一个像素RGB中的R值,第二列是G值这样。

第二个参数是samples的一个mask。比如samples总共有200行,但是奇数行不用来训练,那么就可以用这个mask。否则传一个空的mat。

第三个参数是用来指定GMM的一些参数,诸如有几个gaussian,协方差矩阵的类型,EM算法中迭代的步数,gaussian的均值等等。

第四个参数指定了某些sample的label,就是说对于某个sample具体的最可能属于第几个gaussian这样。

以下代码生成了100个sample用作GMM的数据,并且训练了GMM:

CvEM gmmModel;
CvEMParams emPs(3);//随便设定一个参数,实际应用的时候要看官方的文档
Mat gmmSamples;
for(i = 0; i < 100; i++){
Mat sample(1, 3, CV_8U);
sample.at<uchar>(0) = i;
sample.at<uchar>(1) = i+10;
sample.at<uchar>(2) = i*2;
gmmSamples.push_back(sample);
}

gmmModel.train(gmmSamples, Mat(), emPs, NULL);


float CvEM::predict(const Mat& sample, Mat* probs=0 )


给定一个sample,根据已有的GMM模型来做出预测。注意到虽然这货返回的是float,但是这个float实际上是表示给定的这个sample,最可能属于GMM众多gaussian中的哪个,所以这个float表示的其实是下标。这对于用GMM做聚类是没有问题的,但是如果是用GMM做类似背景建模这样是不行的,所以还要加进去别的工作。在这里就要给第二个参数probs传进一个Mat,这样就可以得到对test
sample,每个gaussian的后验概率。以下predict的使用实例代码:

Mat testSample(1, 3, CV_8U), probs, weights;
weights = gmmModel.getWeights();//在这里得到每个gaussian在这个GMM中的权重
gmmModel.predict(sample, &probs);//如果是聚类的话这里就可以结束了
float pro_test = probs.at<double>(0) * weights.at<double>(0) +
probs.at<double>(1) * weights.at<double>(1) +
probs.at<double>(2) * weights.at<double>(2);
//把后验概率乘上对应的权重就得到了test sample在这个GMM的概率


差不多实际上也就把CvEM这个类给说完了,更多的详细设定可以参考官方文档。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv