2012-04-02 23 views
14

Sto cercando un modo efficiente per modificare/leggere i pixel dalla variabile Mat (o Mat3b).Come modificare/leggere i valori dei pixel in OpenCv dalla variabile Mat?

ho usato: -

Image.at<Vec3b>(i,j) 

ma sembra essere molto lento.

Ho usato anche questo: -

A.data[A.channels()*A.cols*i + j + 0] 

ma il problema che sto affrontando con questo è quando ho eseguito questo ciclo

for(i=0; j<A.rows; i++){ 
    for(j=0; j<A.cols; j++){ 
      A.data[A.channels()*A.cols*i + j + 0] = 0; 
      A.data[A.channels()*A.cols*i + j + 1] = 0; 
      A.data[A.channels()*A.cols*i + j + 2] = 0; 
    } 
} 

solo una parte dell'immagine è annerito.

+0

Ci sono il modo più veloce per accedere agli elementi Mat, come la risposta accettata giustamente, ma esegue il programma in modalità di uscita sarà di accelerare molto il tappetino .at () accessi. Saranno leggermente più lenti dell'accesso puntatore – Sam

risposta

18

Here si possono vedere alcune delle possibilità di accesso elemento veloce.

Ma se vuoi farlo a modo tuo, devi aggiungere una parentesi. Altrimenti indice di calcolo non è corretto:

for(int i=0; i<A.rows; i++){ 
    for(int j=0; j<A.cols; j++){ 
      A.data[A.channels()*(A.cols*i + j) + 0] = 0; 
      A.data[A.channels()*(A.cols*i + j) + 1] = 0; 
      A.data[A.channels()*(A.cols*i + j) + 2] = 0; 
    } 
} 

Ma il layout della memoria non è garantito per essere contigue a causa di imbottitura. Quindi secondo this si dovrebbe piuttosto utilizzare una formula come questo:

for(int i=0; i<A.rows; i++){ 
    for(int j=0; j<A.cols; j++){ 
      A.data[A.step[0]*i + A.step[1]* j + 0] = 0; 
      A.data[A.step[0]*i + A.step[1]* j + 1] = 0; 
      A.data[A.step[0]*i + A.step[1]* j + 2] = 0; 
    } 
} 
+0

A.data [A.step [0] * i + A.step [1] * j + 0] = 0; Questa riga mi sta dando errori. –

+2

Ho usato A.data [A.step * i + A.channels() * j + 0], funziona bene. Grazie, ci vuole molto meno tempo rispetto al metodo precedente. :) –

14

Questo è uno dei modi più efficienti per modificare/leggere i pixel da cv :: Mat. Creare puntatore ad una fila (di canale specifico, se necessario)

for(int i=0; i<A.rows;i++){ 
    uchar* rowi = A.ptr/*<uchar>*/(i); 
    for(int j=0; j<A.cols; j++){ 
    doProcessOnPixel(rowi[j]); 
    } 
} 
Problemi correlati