OpenCV: extraction de la couleur basée sur le modèle de mélange Gaussien
Je suis en train d'utiliser opencv algorithme EM pour faire extraction de la couleur.Je suis en utilisant le code suivant basé sur l'exemple dans opencv documentation:
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;
}
}
Ma question ici est:
Tout d'abord, je veux extraire chaque modèle, ici totalement de cinq, puis de stocker ces correspondante des valeurs de pixel dans cinq différentes de la matrice. Dans ce cas, je pourrais avoir cinq différentes couleurs séparément. Ici, j'ai seulement obtenu leur index, est-il un moyen pour atteindre leurs couleurs correspondantes ici? Pour le rendre facile, je peux commencer de trouver la couleur dominante sur la base de ces cinq Mgm.
Deuxièmement, voici mon exemple de points de données sont "100", et il faut à peu près 3 secondes. Mais je veux faire toutes ces choses dans pas plus de 30 millisecondes. Je sais OpenCV fond d'extraction, qui consiste à utiliser GMM, effectue très rapidement, en dessous de 20 ms, ce qui signifie, il doit y avoir un moyen pour moi de faire toutes ces dans un délai de 30 ms pour toutes les 600 x 800=480000 pixels. J'ai trouvé predict
de la fonction est le plus de temps.
cette question a été un ancien, mais après j'ai demandé à une autre question que vous avez répondu, j'ai mis à jour celui-ci avec l'extraction de la couleur et de la vitesse de calcul. Pourriez-vous m'aider? Je vous remercie.
Je n'ai pas vraiment compris la question. L'extraction de couleurs ne fait pas de sens pour moi. Êtes-vous essayer de calculer les couleurs dominantes? Ou quantifier les couleurs? Votre code ne pas m'aider beaucoup. Concernant le problème de vitesse, à l'aide de
params.cov_mat_type = COV_MAT_DIAGONAL
est suffisant pour la plupart des cas, et permettra d'accélérer votre processus deJe suis en train d'extraire chaque couleur d'une scène, en commençant par le dominant. Merci de m'aider sur ce sujet. Je vous remercie.
J'ai essayé le "params.cov_mat_type = COV_MAT_DIAGONAL" mais elle n'a pas une grosse différence.
OriginalL'auteur E_learner | 2012-09-19
Vous devez vous connecter pour publier un commentaire.
Première Question:
Afin de faire extraction de la couleur, vous devez d'abord le train de l'EM avec votre entrée pixels. Après cela, il vous suffit de boucler sur tous les pixels de nouveau et utiliser predict() pour classer chacun d'eux. J'ai joint un petit exemple qui utilise EM pour l'avant-plan/arrière-plan de séparation basée sur les couleurs. Il vous montre comment extraire la couleur dominante (moyenne) de chaque gaussienne et comment accéder à l'origine de la couleur des pixels.
J'ai testé le code avec l'image suivante et il fonctionne très bien.
Deuxième Question:
J'ai remarqué que le nombre maximal de clusters a un impact énorme sur les performances. Il est donc préférable de la mettre à une très conservatrice de la valeur plutôt que de la laisser vide ou le paramètre le nombre d'échantillons comme dans votre exemple. En outre, la documentation mentionne une procédure itérative à plusieurs reprises optimiser le modèle avec le moins de contraintes paramètres. Peut-être que cela vous donne un peu de vitesse. Pour en savoir plus, veuillez regarder les docs à l'intérieur de l'échantillon de code est fourni pour le train() ici.
Eh bien, suis-je en droit de penser que vous souhaitez appliquer l'algorithme en temps réel de certains flux de l'image? Si oui, peut-être avez-vous pas besoin de former les EM dans chaque image, mais le train, avec la première image et ensuite il suffit de prévoir dans les images consécutives ou si vous avez besoin de former de chaque image, puis commencer avec les valeurs de la précédente train et COV_MAT_DIAGONAL (Veuillez consulter le code de la doc à l'intérieur de l'exemple donné dans la OpenCV documentation pour le train de la méthode)
il n'est pas l'entraînement de l'oreille de la partie qui demande beaucoup de temps, mais c'est le "prédire". Je suis remise de trames vidéo, et pour la prédiction de 600 x 800 de la taille d'image, il faut environ 3 secondes! Avez-vous une autre idée pour l'accélérer?
Eh bien, si vous essayez de suivre un objet, vous pouvez faire usage de cohérence spatiale et d'appliquer predict() juste pour un petit patch autour de la dernière position connue de l'objet. Par exemple, le patch peut être un cercle qui est positionné sur le dernier cours connu sur le centre de gravité de l'objet et a un rayon d'un peu plus grand que le dernier rayon. Bien sûr, vous pouvez utiliser des approches plus sophistiquées comme Kalman, Filtrage, mais pour un démarrage rapide ce devrait être suffisant.
Je vous remercie beaucoup pour votre suggestion. En attendant, je me demande comment pourrait OpenCV MoG est capable de soustraire les milieux à l'aide de GMM si vite? J'ai regardé dans le code, semble comme c'est à l'aide de k-means, mais vous ne savez pas, mais ne pouvait toujours pas comprendre pleinement. Pour la même image de la vidéo, il utilise seulement environ 30 ms.
OriginalL'auteur AD-530