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 ;
}
}
3 Réponses :
Je suppose que le deuxième est correct, il est néanmoins que beaucoup de temps pratiquent d'obtenir les données comme ça. p>
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 ... P>
"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 * code> et incrémenter l'adresse pointée avec la taille des données contenues dans ROI" I> - Ê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 Code> 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 Code> S comme pour iplimage code> s). La boucle imbriquée est donc toujours là, mais ok vous pouvez optimiser la multiplication par widthstep code> comme vous avez dit (si le compilateur ne le fait pas).
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 code> iplimage code>, 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> < P> (dans le code suivant, pour une approche plus flexible, Vous pouvez utiliser le img code> est de type iplimage code>.) p> cv_image_elem code> macro défini dans type_c.h code>: p>
Qu'est-ce qui vous fait penser que ce n'est pas exactement b> 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.
Le second est correct, Les rangées et les cols à l'intérieur du tapis représentent le nombre de pixels, Pendant que le canal n'a rien à voir avec les rangées et les colons. et CV Utilisez BGR par défaut, supposant que le tapis n'est pas converti en RVB, le code est correct p>
Référence, expérience personnelle, Documents OpenCV A > p>
La seconde est correcte. Vérifiez les docs pour plus de détails
En voir plus ans 1 et