我在opencv文档中的示例代码的帮助下使用opencv EM算法获取GMM模型,如下所示:
cv::Mat capturedFrame
const int N = 5;
int nsamples = 100;
cv::Mat samples ( nsamples, 2, CV_32FC1 );
samples = samples.reshape ( 2, 0 );
cv::Mat sample ( 1, 2, CV_32FC1 );
CvEM em_model;
CvEMParams params;
for ( i = 0; i < N; i++ )
{
//from the training samples
cv::Mat samples_part = samples.rowRange ( i*nsamples/N, (i+1)*nsamples/N);
cv::Scalar mean (((i%N)+1)*img.rows/(N1+1),((i/N1)+1)*img.rows/(N1+1));
cv::Scalar sigma (30,30);
cv::randn(samples_part,mean,sigma);
}
samples = samples.reshape ( 1, 0 );
//initialize model parameters
params.covs = NULL;
params.means = NULL;
params.weights = NULL;
params.probs = NULL;
params.nclusters = N;
params.cov_mat_type = CvEM::COV_MAT_SPHERICAL;
params.start_step = CvEM::START_AUTO_STEP;
params.term_crit.max_iter = 300;
params.term_crit.epsilon = 0.1;
params.term_crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
//cluster the data
em_model.train ( samples, Mat(), params, &labels );
作为刚接触GMM和openCV的人,现在我有一些问题:
首先,执行完上述代码后,我可以得到如下问题:
cv::Mat probs = em_model.getProbs();
然后,如何获得具有最多和最少元素的模型,即最大和最小模型?
其次,,这里的样本数据仅为100,如opencv的示例代码中所示,但我正在读取尺寸为600x800的帧,并且我想对其中的所有这些像素进行采样,即480000。但是大约需要10个像素这100个样本的毫秒数,这意味着如果我设置以下参数,它将太慢:
int nsamples = 480000;
我在这里正确吗?
最佳答案
如果我的问题正确,您所说的“最大”和“最小”模型是指混合物中每个高斯的权重。您可以使用 EM::getWeights
获得与高斯相关的权重。
关于第二个问题,如果您使用480000个样本而不是100个样本训练模型,是的,肯定会更长。 “太慢”取决于您的要求。但是EM是分类模型,因此通常要做的是必须使用足够数量的样本来训练模型。这是一个漫长的过程,但通常是“离线”完成的。然后,您可以使用模型“预测”新样本,即获取与新输入样本相关的概率。调用getProbs()
函数时,您将获得与训练样本相关的概率。如果要获取未知样本(通常是视频帧中的像素)的概率,请调用函数 predict
。
关于video - OpenCV:如何对GMM计算的概率进行分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12909343/