2013-05-07 19 views
6

Conosco bene il formato dell'immagine IPL utilizzato in OpenCV 1.1. Comunque sto usando l'ultima versione 2.4 e voglio passare all'interfaccia C++ di OpenCV. Ecco il metodo con cui accedo al pixel in un'immagine:Da IPLImage a 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; 
    } 
} 

Ho bisogno di aiuto per la conversione di questo blocco di codice esatto con la struttura Mat. Trovo molte funzioni qua e là ma sarà molto utile se ottengo la conversione esatta delle poche righe sopra nel suo complesso.

risposta

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

Innanzitutto, è possibile eseguire la stessa operazione su IPLImage e utilizzare il costruttore incorporato di Mat per convertirlo.

In secondo luogo, il tuo codice sembra essere eccessivamente complicato, poiché stai facendo la stessa operazione per tutte e 3 le dimensioni. Quanto segue è più ordinato (nella notazione 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; 
} 

Se si desidera che i THRES per i canali di essere diversi, quindi:

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

Fare tutto IPL-immagine e poi riconversione - sarà questo essere abbastanza veloce? Non voglio che questo processo richieda del tempo di elaborazione extra. E per quella cosa di complicazioni - questo è solo un codice di esempio, supponiamo di dover dare soglie diverse per il rosso verde e il blu. Il tuo metodo funzionerà allora? – Soumyajit

+1

Quando converti tra Mat e IplImage, hai la possibilità di copiare i dati o meno. Se non si copia, l'overhead è veramente piccolo. Anche se copi, dubito che il sovraccarico sia significativo dato che l'intera elaborazione richiede più di 1 secondo. Aggiunto il caso per diverse soglie. – guinny

+0

Il codice non funziona se la matrice ha un passo. Questo è il caso, ad es. per intestazioni matrix create come una ROI di un'altra matrice. Utilizza gli iteratori o l'accesso al puntatore a riga per evitare tali errori! – ypnos

Problemi correlati