2012-06-05 10 views
6

Qual è il modo più elegante ed efficiente per convertire un nidificato std::vector di std::vector s per cv::Mat? La struttura nidificata contiene un array, ovvero tutti gli interni std::vector hanno la stessa dimensione e rappresentano le righe della matrice. Non mi interessa che i dati vengano copiati da uno all'altro.Convertire uno std :: vector <std :: vector <double>> che rappresenta una matrice 2D per cv :: Mat

So che un singolo, non annidata std::vector è molto facile, c'è un costruttore:

std::vector <double> myvec; 
cv::Mat mymat; 

// fill myvec 
bool copy = true; 

myMat = cv::Mat(myvec, copy); 

Che dire del vettore annidato?

+1

Definire "elegante ed efficiente". –

+0

Qual è il vettore vettoriale che dovrebbe rappresentare? È un vettore di righe di matrice, o colonne o qualcos'altro? –

+0

È un vettore di righe matriciali, l'ho modificato. @John Dibling "elegante ed efficiente" - Non voglio un chunk di codice lungo 3 miglia, e non voglio fare copie in eccesso del dati. – penelope

risposta

4

questo è un modo per farlo:

std::vector<double> row1; 
row1.push_back(1.0); row1.push_back(2.0); row1.push_back(3.0); 

std::vector<double> row2; 
row2.push_back(4.0); row2.push_back(5.0); row2.push_back(6.0); 

std::vector<std::vector<double> > vector_of_rows; 
vector_of_rows.push_back(row1); 
vector_of_rows.push_back(row2); 

// make sure the size of of row1 and row2 are the same, else you'll have serious problems! 
cv::Mat my_mat(vector_of_rows.size(), row1.size(), CV_64F); 

for (size_t i = 0; i < vector_of_rows.size(); i++) 
{ 
    for (size_t j = 0; j < row1.size(); j++) 
    { 
     my_mat.at<double>(i,j) = vector_of_rows[i][j]; 
    } 
} 

std::cout << my_mat << std::endl; 

Uscite:

[1, 2, 3; 
    4, 5, 6] 

ho cercato un altro approccio utilizzando il costruttore di Mat e il metodo push_back() ma senza successo, forse si può capire su. In bocca al lupo!

+0

Immagino che preferisca trattare il vettore vettoriale come un vettore di righe o colonne della matrice. –

+0

@ChristianRau Grazie, ho aggiornato la risposta. – karlphillip

+0

'cv :: Mat my_mat = cv :: Mat (vector_of_rows.size(), row1.size(), CV_64F);'? non è elegante :-) – fireant

7

mio variante (richiede OpenCV 2.4):

int size = 5; 
vector<vector<double> > w(size); 
for(int i = 0; i < size; ++i) 
{ 
    w[i].resize(size); 
    for(int j = 0; j < size; ++j) 
     w[i][j] = (i+1) * 10 + j; 
} 

Mat m(size, size, CV_64F); 
for(int i = 0; i < w.size(); ++i) 
    m.row(i) = Mat(w[i]).t(); 

cout << m << endl; 

Uscite:

[10, 11, 12, 13, 14; 
    20, 21, 22, 23, 24; 
    30, 31, 32, 33, 34; 
    40, 41, 42, 43, 44; 
    50, 51, 52, 53, 54] 

Spiegazione di m.row(i) = Mat(w[i]).t():

  • m.row(i) imposta la ROI, che punti a matrice origine
  • .139.328.994,47321 milioni avvolge vettore senza dati copiare
  • .t() crea "espressione matrice" - no copiatura dei dati svolta
  • = Valuta expression matrice ma perché vettoriale è avvolto nella (size x 1) matrice continua che viene valutata senza una reale trasposizione con un singolo chiamare allo memcpy.