2012-06-05 13 views
6

¿Cuál es la forma más elegante y eficiente para convertir una anidada std::vector de std::vector s a cv::Mat? La estructura anidada contiene una matriz, es decir, todas las std::vector internas tienen el mismo tamaño y representan las filas de la matriz. No me importa que los datos se copien de uno a otro.Convierte un std :: vector <std :: vector <double>> representa una matriz 2D a cv :: Mat

sé que una sola, no anidada std::vector es muy fácil, hay un constructor:

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

// fill myvec 
bool copy = true; 

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

¿Qué pasa con el vector anidada?

+1

Definir "elegante y eficiente". –

+0

¿Qué se supone que representa el vector-vector? ¿Es un vector de filas, columnas o algo más de la matriz? –

+0

Es un vector de filas de matriz, lo edité en. @John Dibling "elegante y eficiente" - No quiero un fragmento de código de 3 millas de largo, y no quiero hacer copias en exceso del datos. – penelope

Respuesta

4

Esta es una manera de hacerlo:

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; 

Salidas:

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

me trataron otro enfoque utilizando el constructor de Mat y el método push_back() pero sin éxito, tal vez usted puede imaginarlo fuera. ¡Buena suerte!

+0

Supongo que prefiere tratar el vector vector como un vector de filas o columnas de la matriz. –

+0

@ChristianRau Gracias, actualicé la respuesta. – karlphillip

+0

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

7

Mi variante (requiere 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; 

Salidas:

[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] 

Explicación de m.row(i) = Mat(w[i]).t():

  • m.row(i) establece el ROI, apunta a matriz original
  • Mat(w[i]) envuelve vector sin datos de la copia de
  • .t() crea "expresión matriz" - no la copia de datos realiza
  • = evalúa la expresión matriz sino porque vector se envuelve en el (size x 1) matriz continua se evalúa sin transposición real con una sola llama al memcpy.
Cuestiones relacionadas