Я пытаюсь использовать алгоритм opencv EM для извлечения цвета. Я использую следующий код на основе примера в документации opencv:
cv::Mat capturedFrame ( height, width, CV_8UC3 );
int i, j;
int nsamples = 1000;
cv::Mat samples ( nsamples, 2, CV_32FC1 );
cv::Mat labels;
cv::Mat img = cv::Mat::zeros ( height, height, CV_8UC3 );
img = capturedFrame;
cv::Mat sample ( 1, 2, CV_32FC1 );
CvEM em_model;
CvEMParams params;
samples = samples.reshape ( 2, 0 );
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 );
cv::Mat probs;
probs = em_model.getProbs();
cv::Mat weights;
weights = em_model.getWeights();
cv::Mat modelIndex = cv::Mat::zeros ( img.rows, img.cols, CV_8UC3 );
for ( i = 0; i < img.rows; i ++ )
{
for ( j = 0; j < img.cols; j ++ )
{
sample.at<float>(0) = (float)j;
sample.at<float>(1) = (float)i;
int response = cvRound ( em_model.predict ( sample ) );
modelIndex.data [ modelIndex.cols*i + j] = response;
}
}
Мой вопрос вот в чем:
Во-первых, я хочу извлечь каждую модель, здесь всего пять, а затем сохранить соответствующие значения пикселей в пяти разных матрицах. В этом случае у меня может быть пять разных цветов по отдельности. Здесь я получил только их индексы, есть ли способ добиться здесь соответствующих им цветов? Чтобы упростить задачу, я могу начать с поиска доминирующего цвета на основе этих пяти GMM.
Во-вторых, здесь мои выборочные точки данных равны "100", и для них требуется около 3 секунд. Но я хочу сделать все это не более чем за 30 миллисекунд. Я знаю, что извлечение фона OpenCV, в котором используется GMM, выполняется очень быстро, менее 20 мс, это означает, что у меня должен быть способ сделать все это в течение 30 мс для всех 600x800 = 480000 пикселей. Я обнаружил, что функция predict
занимает больше всего времени.
params.cov_mat_type = COV_MAT_DIAGONAL
, и это ускорит ваш процесс. - person remi   schedule 20.10.2012