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;
}
}
ここでの私の質問は次のとおりです。
まず、ここでは合計 5 つの各モデルを抽出し、対応するピクセル値を 5 つの異なるマトリックスに格納します。この場合、5 つの異なる色を別々に使用できます。ここではインデックスのみを取得しましたが、ここで対応する色を実現する方法はありますか? 簡単にするために、これら 5 つの GMM に基づいてドミナント カラーを見つけることから始めます。
次に、ここで私のサンプル データポイントは「100」で、約 3 秒かかります。しかし、これらすべてを 30 ミリ秒以内で実行したいと考えています。GMM を使用している OpenCV バックグラウンド抽出が 20 ミリ秒未満で非常に高速に実行されることはわかっています。つまり、すべての 600x800=480000 ピクセルに対して 30 ミリ秒以内にこれらすべてを実行する方法が必要です。predict
関数が最も時間がかかることが わかりました。