2013-05-07 10 views
6

Jestem dobrze obeznany z formatem obrazu IPL używanym w OpenCV 1.1. Jednak używam najnowszej wersji 2.4 i chcę przejść do interfejsu C++ OpenCV. Oto metoda, dzięki której dostęp do pikseli w obrazie:Od IPLImage do Mat

int step = img->widthStep; 
int height = img->height; 
int width = img->width; 
unsigned char* data = (unsigned char*) img->imageData; 

for (int i=0; i<height; i++) 
{ 
    for (int j=0; j<step; j+=3)   // 3 is the number of channels. 
    { 
     if (data[i*step + j] > 200)  // For blue 
      data[i*step + j] = 255; 

     if (data[i*step + j + 1] > 200) // For green 
      data[i*step + j + 1] = 255; 

     if (data[i*step + j + 2] > 200) // For red 
      data[i*step + j + 2] = 255; 
    } 
} 

Potrzebuję pomocy do konwertowania dokładnie ten blok kodu ze strukturą Mat. Znajduję kilka funkcji tu i tam, ale bardzo pomocne będzie uzyskanie dokładnej konwersji powyższych kilku linii jako całości.

Odpowiedz

8
// Mat mat; // a bgr, CV_8UC3 mat 

for (int i=0; i<mat.rows; i++) 
{ 
    // get a new pointer per row. this replaces fumbling with widthstep, etc. 
    // also a pointer to a Vec3b pixel, so no need for channel offset, either 
    Vec3b *pix = mat.ptr<Vec3b>(i); 
    for (int j=0; j<mat.cols; j++) 
    { 
     Vec3b & p = pix[j]; 
     if (p[0] > 200) p[0] = 255; 
     if (p[1] > 200) p[1] = 255; 
     if (p[2] > 200) p[2] = 255; 
    } 
} 
3

Po pierwsze, można zrobić taką samą operację na IPLImage i przy użyciu wbudowanego konstruktora Mat aby ją przekształcić.

Po drugie, Twój kod wydaje się zbyt skomplikowany, ponieważ wykonujesz tę samą operację dla wszystkich 3 wymiarów. Poniżej porządniej (w notacji Mat):

unsigned char* data = (unsigned char*) img.data; 

for (int i = 0; i < image.cols * image.rows * image.channels(); ++i) { 
    if (*data > 200) *data = 255; 
    ++data; 
} 

Jeśli chcesz, Thres dla kanałów być różne, a następnie:

unsigned char* data = (unsigned char*) img.data; 
assert(image.channels() == 3); 

for (int i = 0; i < image.cols * image.rows; ++i) { 
    if (*data > 200) *data = 255; 
    ++data; 
    if (*data > 201) *data = 255; 
    ++data; 
    if (*data > 202) *data = 255; 
    ++data; 
} 
+0

robi wszystko w IPL-obrazie, a następnie konwersja z powrotem - to będzie być wystarczająco szybki? Nie chcę, aby proces ten wymagał dodatkowego czasu przetwarzania. I w tym przypadku komplikacji - to tylko przykładowy kod, przypuśćmy, że muszę podać różne progi dla czerwonego zielonego i niebieskiego. Czy twoja metoda zadziała wtedy? – Soumyajit

+1

Po konwersji między Mat i IplImage, masz opcję kopiowania danych lub nie. Jeśli nie kopiujesz, obciążenie jest naprawdę małe. Nawet jeśli skopiujesz, wątpię, aby koszty ogólne były znaczące, biorąc pod uwagę, że całe przetwarzanie trwa dłużej niż 1 sekundę. Dodano przypadek dla różnych progów. – guinny

+0

Twój kod nie działa, jeśli macierz ma krok. Tak jest w przypadku np. dla nagłówków macierzy utworzonych jako ROI innej macierzy. Użyj iteratorów lub dostępu do wiersza, aby uniknąć takich błędów! – ypnos