2012-09-09 9 views
10

Podczas pracy z obiektami matowymi 1-kanałowymi (na przykład CV_8UC1) w OpenCV tworzy to Matę wszystkich: cv::Mat img = cv::Mat::ones(x,y,CV_8UC1).OpenCV cv :: Mat 'ones' dla macierzy wielokanałowej?

Jednak, gdy używam obrazów 3-kanałowych (np. CV_8UC3), rzeczy stają się nieco bardziej skomplikowane. Wykonanie cv::Mat img = cv::Mat::ones(x,y,CV_8UC3) powoduje wstawienie z nich do kanału 0, ale kanały 1 i 2 zawierają zer. Jak zatem użyć obrazów cv::Mat::ones() dla obrazów wielokanałowych?

Oto niektóre kodu, które mogą pomóc, aby zobaczyć, co mam na myśli:

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 
} 

Tak, spodziewałem się, aby zobaczyć ten wydruk: px of 3-channel img: 1 1 1, lecz widzę to: px of 3-channel img: 1 0 0.

P.S. Zanim napisałem to, wiele szukałem. Nie mogłem tego rozwiązać, wyszukując SO dla "[opencv] Mat :: ones" lub "[opencv] + mat + ones".

+1

Sidenote: Nie jestem pewien, czy powinienem użyć ' uchar' zamiast "cv :: Vec3b" dla 1-kanałowego piksela obrazu. OpenCV oferuje wiele klas wektorów 2-, 3- i 4-elementowych, ale nie ma analogii do singletonu. (Wyszukaj 'Vec3b' na tej stronie: http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#vec) – solvingPuzzles

Odpowiedz

6

Nie używam OpenCV, ale wierzę, że wiem, co się tutaj dzieje. Użytkownik definiuje typ danych, ale żąda od niego wartości "1". Klasa Mat wydaje się nie zwracać uwagi na fakt, że masz wielokanałowy typ danych, więc po prostu rzuca "1" jako 3-bajtowy znak bez znaku.

Więc zamiast używania funkcji ones, wystarczy użyć konstruktora skalarnego:

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

Właśnie wypróbowałem twoje rozwiązanie. 'cv :: Mat img_C3 = cv :: Mat :: ones (x, y, CV_8UC3) * CV_RGB (1,1,1);' nie kompiluje się, ponieważ nie ma przeciążonego operatora '*' dla typ 'cv :: Mat'. 'cv :: Mat img_C3 (x, y, CV_8UC3, CV_RGB (1,1,1));' kompiluje, ale definiuje kanały piksela jako '1 0 0', tak jak w przykładzie' one' z mojego pytania . Głębię teraz twoją odpowiedź. – solvingPuzzles

+1

O, czekaj, 'cv :: Mat img_C3 (x, y, CV_8UC3, CV_RGB (1,1,1));' DOES działa poprawnie! – solvingPuzzles

+0

Spodziewam się, że pierwsze rozwiązanie zadziała, bazując na tym, gdzie je znalazłem (http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#cv-mon-ones), ale być może nie działa z typ zwracany dla 'CV_RGB'. Napisałem pierwotnie 0x10101, zanim natknąłem się na to makro. Wypróbuj to, a jeśli zadziała, dostosuję proponowane zmiany. – paddy

1

Można również zainicjować tak:

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));