2012-09-09 7 views
10

Lorsque vous travaillez avec des objets Mat à 1 canal (par exemple CV_8UC1) dans OpenCV, ceci crée un Mat de tous ceux: cv::Mat img = cv::Mat::ones(x,y,CV_8UC1). Cependant, lorsque j'utilise des images à 3 canaux (par exemple, CV_8UC3), les choses deviennent un peu plus compliquées. En faisant cv::Mat img = cv::Mat::ones(x,y,CV_8UC3), met dans le canal 0, mais les canaux 1 et 2 contiennent les . Alors, comment utiliser cv::Mat::ones() pour les images multicanaux?OpenCV cv :: Mat 'ceux' pour la matrice multi-canal?

est ici un code qui pourrait vous aider à voir ce que je veux dire:

void testOnes() { 
int x=2; int y=2; //arbitrary 

// 1 channel 
cv::Mat img_C1 = cv::Mat::ones(x,y,CV_8UC1); 
uchar px1 = img_C1.at<uchar>(0,0); //not sure of correct data type for px in 1-channel img 
printf("px of 1-channel img: %d \n", (int)px1); //prints 1 

// 3 channels 
cv::Mat img_C3 = cv::Mat::ones(x,y,CV_8UC3); //note 8UC3 instead of 8UC1 
cv::Vec3b px3 = img_C3.at<cv::Vec3b>(0,0); 
printf("px of 3-channel img: %d %d %d \n", (int)px3[0], (int)px3[1], (int)px3[2]); //prints 1 0 0 
} 

Alors, je me serais attendu à voir cette impression: px of 3-channel img: 1 1 1, mais je vois ceci: px of 3-channel img: 1 0 0.

P.S. J'ai fait beaucoup de recherches avant de poster ceci. Je n'ai pas pu résoudre ce problème en recherchant SO pour "[opencv] Mat :: ones" ou "[opencv] + mat + ones".

+1

Sidenote: Je ne sais pas si je devrais utiliser ' uchar' à la place de 'cv :: Vec3b' pour un pixel d'image à 1 canal. OpenCV offre beaucoup de classes de vecteurs à 2, 3 et 4 items, mais pas d'analogie pour un singleton. (Rechercher 'Vec3b' sur cette page: http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#vec) – solvingPuzzles

Répondre

6

Je n'utilise pas OpenCV, mais je crois savoir ce qui se passe ici. Vous définissez un type de données, mais vous demandez la valeur '1' pour cela. La classe Mat semble ne pas prêter attention au fait que vous avez un type de données multicanal, donc il lance simplement '1' comme un char non signé de 3 octets.

Ainsi, au lieu d'utiliser la fonction ones, il suffit d'utiliser le constructeur scalaire:

cv::Mat img_C3(x, y, CV_8UC3, CV_RGB(1,1,1)); 
+0

Je viens d'essayer votre solution. 'cv :: Mat img_C3 = cv :: Mat :: ones (x, y, CV_8UC3) * CV_RGB (1,1,1);' ne compile pas, car il n'y a pas d'opérateur surchargé '*' pour le Type 'cv :: Mat'. 'cv :: Mat img_C3 (x, y, CV_8UC3, CV_RGB (1,1,1));' compile, mais définit les canaux d'un pixel comme '1 0 0', tout comme dans l'exemple' ones 'de ma question . Je suis en train de creuser votre réponse plus profondément maintenant. – solvingPuzzles

+1

Oh, attendez, 'cv :: Mat img_C3 (x, y, CV_8UC3, CV_RGB (1,1,1));' Fonctionne correctement! – solvingPuzzles

+0

Je m'attendrais à ce que la première solution fonctionne, en fonction de l'endroit où je l'ai trouvé (http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#cv-mat-ones), mais peut-être que cela ne fonctionne pas avec le type de retour pour 'CV_RGB'. J'ai d'abord écrit 0x10101 avant de trébucher sur cette macro. Essayez cela, et si cela fonctionne, je vais ajuster vos modifications proposées. – paddy

1

Vous pouvez également initialiser comme ceci:

Mat img; 

/// Lots of stuff here ... 

// Need to initialize again for some reason: 
img = Mat::Mat(Size(width, height), CV_8UC3, CV_RGB(255,255,255));