2012-08-27 12 views
18

En mi aplicación, quiero crear una OpenCV Mat A (2-Dimensiones) que tenga algunos valores y luego pasarla a otra función OpenCV usando A como entrada.inicializar una Mat OpenCV con una matriz 2D

Actualmente, estoy tratando:

// float data[2][5] = {{1,2,3,4,5},{7,8,9,10,11}}; 
// OR 
float data[10] = {1,2,3,4,5,7,8,9,10,11}; 

// and then 
// A = Mat(1, 5, CV_32FC1, &data, 2); // init from float 1D - array 
// OR 
    A = Mat(2, 5, CV_32FC1, &data, 2); 

en el caso de la matriz 1D, el valor que pasa está bien. Pero esto no funciona para la matriz 2D, que es un caso aún más común. ¿Cómo puedo resolver esto en OpenCV?

Respuesta

23

originalmente, he utilizado la mnemotécnica de guías en línea OpenCV:

Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP) 

Pero yo no entendía lo que significa el documento "paso size_t = AUTO_STEP". Y esto significa que puedo ommit argumento 'paso' con la que OpenCV se elige automáticamente AUTO_STEP

He tratado y esto funciona:

A = Mat(2, 5, CV_32FC1, &data); 

para el Mat 2D inicializado de la matriz

16

Mientras que su la respuesta es correcta para su situación, es bueno saber qué step y AUTO_STEP significa

Por lo general, las imágenes se almacenan en bloques continuos de memoria. Cada fila sigue después de la anterior, por lo que puede acceder a los datos del puntero con un simple

data = dataPtr[currentCol + width * currentRow]; 

Dónde ancho es el ancho de la hilera en bytes (no en píxeles!)

Pero esto no es siempre el caso: a veces accede a una submatriz y los datos son continuos en cada fila, pero para ir a la siguiente fila tiene que saltar una secuencia de bytes.

Aquí es donde entra el paso (también conocido como zancada). Representa la distancia, en bytes, entre dos filas consecutivas. En matrices continuas, su valor es sizeof(pixel)*rowWidth, pero puede tener valores personalizados en situaciones especiales. Cuando pasa AUTO_STEP al constructor Mat, sabe que los datos son continuos y calcula el paso con la fórmula anterior. Así que ahora, el enfoque más correcto valores de píxel de lectura es

data = dataPtr[currentCol + step * currentRow]; 

que está trabajando para todo tipo de imágenes.

Por último, pero no menos importante, no hay que olvidar que el paso se mide en bytes , no píxeles. Así que si usted tiene un 3-canal de imagen RGB UCHAR, paso será 3*number of pixels, y si usted tiene una imagen int 3 canales, step = 3(channels)*(4=sizeof(int))*(number rows)

5

Desde data es 2D matriz - todos data, &data, *data, data[0], &data[0], y &data[0][0] apuntan a la base de la matriz.Cualquiera de la representación anterior podría elegirse para construir correctamente el Mat en lugar de X en

A = Mat(2, 5, CV_32FC1, X); 

tener tranquilidad ya que los datos es accepted por OpenCV como void* y acceso a los datos por OpenCV es como en line. Prefiero la misma sintaxis para construir Mat desde matrices simples o multidimensionales.

A = Mat(1, 10, CV_32FC1, data); //for 1D array 
A = Mat(2, 5, CV_32FC1, data); //for 2D array 

Volver a la consulta - Tenga en cuenta que, a su construcción de Mat incluso de gama 1D es incorrecta. El parámetro de paso se menciona como 2. Simplemente funcionó, ya que OpenCV overrides el parámetro de paso proporcionado, si el número de filas es 1. Para matrices dimensionales superiores, OpenCV arroja la depuración assertion para el parámetro de paso incorrecto, que usted obtuvo.

14

Además de las respuestas anteriores, hay another option.

Para un dato menor, preferiría el siguiente:

Mat A = (Mat_<float>(2, 5) << 1, 2, 3, 4, 5, 7, 8, 9, 10, 11); 

Usted puede fácilmente obtener el resultado deseado sin la necesidad de definir una variable adicional 'datos'.