OpenCV: как классифицировать расчетные проблемы GMM

Я использую алгоритм opencv EM для получения моделей GMM с помощью примера кода в документации opencv следующим образом:

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. Но для этих 100 семплов требуется около 10 мс, это означает, что было бы слишком медленно, если бы я установил:

int nsamples = 480000;

Я на правильном пути здесь?


person E_learner    schedule 16.10.2012    source источник


Ответы (1)


Если я правильно понял ваш вопрос, то, что вы называете своими «самыми большими» и «самыми маленькими» моделями, относится к весам каждого гауссова в смеси. Вы можете получить веса, связанные с гауссианами, используя EM::getWeights.

Что касается второго вопроса, если вы будете обучать свою модель, используя 480000 образцов вместо 100, да, это будет определенно дольше. Быть «слишком медленным» зависит от ваших требований. Но EM — это классификационная модель, поэтому обычно вы должны обучать модель, используя достаточное количество выборок. Это долгий процесс, но обычно он выполняется в автономном режиме. Затем вы можете использовать модель для «предсказания» новых выборок, т. е. получить вероятности, связанные с новыми входными выборками. Когда вы вызываете функцию getProbs(), вы получаете вероятности, связанные с вашими обучающими выборками. Если вы хотите получить вероятности для неизвестных образцов, обычно пикселей в вашем видеокадре, вызовите функцию predict.

person remi    schedule 16.10.2012
comment
Большое спасибо за ваш ответ. Еще один вопрос: я обнаружил, что прогноз дает мне индекс модели, к которой принадлежит текущий пиксель. Итак, что я хочу сделать, это извлечь те пиксели, которые имеют самые большие и самые маленькие индексы модели, и сохранить их значения пикселей в две разные матрицы. Я попытался сохранить индексы в двух cvScalar и прочитать соответствующие значения пикселей в исходной матрице кадра, но это не работает. Есть ли у вас какие-либо идеи? Еще раз спасибо. - person E_learner; 16.10.2012
comment
предсказание возвращает число с плавающей запятой, соответствующее индексу гауссова с максимальной апостериорной вероятностью. Вы можете передать матрицу в качестве дополнительного аргумента, чтобы предсказать, где будут храниться вероятности, связанные с каждым гауссианом в вашей модели. Используя эту матрицу, вы можете получить минимальную и максимальную вероятности для каждого пикселя. Эта матрица будет иметь строки number_of_samples и столбцы number_of_gaussian, поэтому значение в позиции x, y в этой матрице соответствует апостериорной вероятности выборки x согласно гауссову y. - person remi; 16.10.2012