2013-07-10 15 views
7

In breve, vorrei sapere se è possibile accedere direttamente al valore di pixel di un Mat CV_32F, tramite il membro Mat "uchar * data".OpenCV C++: come il valore del pixel di accesso CV_32F tramite il puntatore di dati uchar

posso farlo senza alcun problema se Mat è CV_8U, ad esempio:

// a matrix 5 columns and 6 rows, values in [0,255], all elements initialised at 12 
cv:Mat A; 
A.create(5,6, CV_8UC1); 
A = cv::Scalar(12); 

//here I successfully access to pixel [4,5] 
uchar *p = A.data; 
int value = (uchar) p[4*A.step + 5]; 

Il problema è quando provo a fare la stessa operazione con la seguente matrice,

// a matrix 5 columns, 6 rows, values in [0.0, 1.0], all elements initialised at 1.2 
cv::Mat B; 
B.create(5,6, CV_32FC1); 
B = cv::Scalar(1.2); 

//this clearly does not work, no syntax error but erroneous value reported! 
uchar *p = B.data; 
float value = (float) p[4*B.step + 5]; 

//this works, but it is not what I want to do! 
float value = B.at<float>(4,5); 

Grazie molto, Valerio

+0

Esiste qualsiasi motivo per non usare 'float * p = B.data'; – William

+2

mmm no, non puoi farlo! B.data è un puntatore a uchar! Questo è un membro dei dati in Mat! –

+0

oups. scusa. mi sono precipitato a commentare. a proposito. vota le risposte che ti sono piaciute e accetta quello che funziona. – William

risposta

5

Nota che CV_32F indica che gli elementi sono float anziché uchar. La "F" qui significa "fluttuare". E la "U" in CV_8U sta per unsigned integer. Forse è per questo che il tuo codice non dà il giusto valore. Dichiarando p come uchar*, p[4*B.step+5] fa p spostare alla quinta riga e avanzare sizeof(uchar)*5, che tendono ad essere errati. Puoi provare

float value = (float) p[4*B.step + 5*B.elemSize()] 

ma non sono sicuro che funzionerà. Ecco alcuni modi per passare i dati di [i, j] per valore:

  1. value = B.at<float>(i, j)
  2. value = B.ptr<float>(i)[j]
  3. value = ((float*)B.data)[i*B.step+j]

Il terzo modo in cui non è consigliabile, però, dal momento che è facile traboccare. Inoltre, una matrice 6x5 dovrebbe essere creata da B.create(6, 5, CV_32FC1), penso?

+0

Grazie, il terzo modo era quello che stavo cercando. Tuttavia, c'è qualcosa che non mi è ancora chiaro. Ho usato questa formula: –

+0

ops, posto sbagliato dove scrivere rispondi? –

+0

Ok, per favore chiarisci questo punto: nella 3a modalità usi il numero 5. Dovresti essere B.step invece il numero 5? Grazie. –

14

È possibile utilizzare ptr metodo che restituisce puntatore alla riga di matrice:

for (int y = 0; y < mat.rows; ++y) 
{ 
    float* row_ptr = mat.ptr<float>(y); 
    for (int x = 0; x < mat.cols; ++x) 
    { 
     float val = row_ptr[x]; 
    } 
} 

È anche possibile convertire data puntatore a galleggiare e utilizzare elem_step anziché step se matrice è continuo:

float* ptr = (float*) mat.data; 
size_t elem_step = mat.step/sizeof(float); 
float val = ptr[i * elem_step + j]; 
+0

Funziona! Grazie. –

+1

funziona anche quando Mat non è continuo. – Kiran

Problemi correlati