我使用opencv EM算法借助opencv文档中的示例代码获取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的帧,我想要对其中的所有像素进行采样,其中这是100个样本需要大约10毫秒,这意味着如果我设置它会太慢:
int nsamples = 480000;
我在正确的路上吗?
答案 0 :(得分:1)
如果我的问题正确,你称之为“最大”和“最小”的模型是指混合物中每个高斯的权重。您可以使用EM::getWeights
获取与高斯人相关的权重。
关于第二个问题,如果你使用480000个样本而不是100个样本训练你的模型,是的,它肯定会更长。 “太慢”取决于您的要求。但EM是一种分类模型,因此通常要做的是必须使用足够量的样本训练模型。这是一个漫长的过程,但通常是“离线”。然后,您可以使用该模型“预测”新样本,即获得与新输入样本相关的概率。当您调用getProbs()
函数时,您将获得与训练样本相关的概率。如果您想获取未知样本的概率,通常是视频帧中的像素,请调用函数predict
。