7
votes

Comment accéder aux valeurs RVB dans OpenCV?

Je suis confus sur l'utilisation du nombre de canaux. Lequel est correct des suivants?

for(int i = 0; i < roi.rows; i++)
{
    for(int j = 0; j < roi.cols; j++)
    {
        int b = roi.at<cv::Vec3b>(i,j)[0];
        int g = roi.at<cv::Vec3b>(i,j)[1];
        int r = roi.at<cv::Vec3b>(i,j)[2];
        cout << r << " " << g << " " << b << endl ;
    }
}


2 commentaires

La seconde est correcte. Vérifiez les docs pour plus de détails


En voir plus ans 1 et


3 Réponses :


0
votes

Je suppose que le deuxième est correct, il est néanmoins que beaucoup de temps pratiquent d'obtenir les données comme ça.

Une méthode plus rapide serait d'utiliser la structure de données IPlimage * et d'incrémenter l'adresse pointée avec la taille des données contenues dans ROI ...


3 commentaires

"Il est très temps de prendre les données comme ça. Une méthode plus rapide serait d'utiliser la structure de données iplimage * et incrémenter l'adresse pointée avec la taille des données contenues dans ROI" - Êtes-vous sûr de cela? Ne devrait pas faire de différence significative (si une différence du tout). Ces méthodes seront toutes inlinées, à l'autre.


Je pense que lorsque vous essayez d'accéder à l'élément I, J, OpenCV calculera la position de l'élément dans la mémoire et le renvoyera (en fonction de la largeur, de la NB des canaux et de la taille de chaque élément de matrice). Ce calcul (largeur réalisée * Height Times) prend plus de temps que d'ajouter 8 bits à l'adresse que vous travaillez.


Je ne sais pas que cela importe vraiment, laissé de côté du compilateur étant assez intelligent pour cela. Mais d'accord, peut-être très bien, mais encore une fois, à nouveau, à l'aide d'un pointeur vers CV :: Vec3b Les données et en augmentant que par 1 ne devraient pas être différentes non plus, aucun Iplimage < / code> s. De toute façon, vous ne pouvez pas traverser la limite de la rangée, car les rangées n'ont pas besoin d'être contiguës dans OpenCV (et cela contient pour CV :: Mat S comme pour iplimage s). La boucle imbriquée est donc toujours là, mais ok vous pouvez optimiser la multiplication par widthstep comme vous avez dit (si le compilateur ne le fait pas).



1
votes

Un moyen plus rapide d'obtenir des composants de couleur à partir d'une image est d'avoir l'image représentée sous la forme d'une structure iplimage , puis utilisez la taille de pixels et le nombre de canaux à parcourir à l'aide d'un pointeur arithmétique.

Par exemple, si vous savez que votre image est une image à 3 canaux avec 1 octet par pixel et son format est BGR (la valeur par défaut dans OpenCV), le code suivant obtiendra l'accès à ses composants: < P> (dans le code suivant, img est de type iplimage .) xxx

pour une approche plus flexible, Vous pouvez utiliser le cv_image_elem macro défini dans type_c.h : xxx


2 commentaires

Qu'est-ce qui vous fait penser que ce n'est pas exactement ce qui est compilé de son 2e exemple?


Arrêtez d'utiliser l'ancienne implémentation IPlimage. Le "deuxième" exemple est valide. Le 2ème exemple, cependant, n'est pas super rapide, mais très lisible. Ce que vous pouvez faire pour accélérer est d'abord diviser les canaux, puis lire à l'aide des pointeurs. Ou, si vous êtes plus intelligent, utilisez immédiatement les pointeurs en prenant en compte la taille de l'étape et en bitsize.