2012-06-08 17 views
23

me di cuenta de que una nueva estructura de datos cv :: Matx se añadió a la nueva versión OpenCV, destinado a las pequeñas matrices de tamaño conocido en tiempo de compilación, por ejemploVentajas de CV :: matx

cv::Matx31f // matrix 3x1 of float type 

Revisando el documentation Vi que la mayoría de las operaciones de la matriz están disponibles, pero aún no veo las ventajas de usar este nuevo tipo en lugar del antiguo cv :: Mat.

¿Cuándo debería usar Matx en lugar de Mat?

+3

Sin mirar demasiado de cerca en la documentación, se puede decir que conocer el tamaño en tiempo de compilación tiene sin duda muchas ventajas, en primer lugar la sustitución de memoria asignada dinámicamente por las matrices de tiempo de compilación, que para este tipo de matrices pequeñas claramente definidos es una optimización obvia Dicho esto, su pregunta responde con bastante claridad: * "destinado a matrices pequeñas de tamaño conocido" *. Piense en las matrices de transformación utilizadas en las transformaciones de imagen o la calibración de la cámara. –

+1

Pero eso todavía se puede hacer con el viejo tipo Mat al poner Mat (3,1, CV_32FC1) –

+1

Claro, por lo tanto, todo mi primer párrafo sobre la optimización obvia de usar matrices de compilación sobre la asignación de memoria dinámica. Por supuesto, es solo una optimización y ninguna funcionalidad adicional, pero esta es exactamente la ventaja que obtienes. Realmente no desea asignar dinámicamente memoria para una matriz estricta de 3x4. –

Respuesta

10

Se trata de la gestión de memoria y no perder (en algunos casos importante) la memoria o simplemente la reserva de memoria para un objeto que utilizará más adelante.

Así es como lo entiendo, puede ser que otra persona pueda dar una mejor explicación.

6

Respuesta corta: cv :: Mat usa el heap para almacenar sus datos, mientras que cv :: Matx usa la pila.

A cv :: Mat utiliza la asignación de memoria dinámica (en el montón). Esto es apropiado para matrices grandes (como imágenes) y le permite hacer cosas como copias superficiales de una matriz, que es el comportamiento predeterminado de cv :: Mat.

Sin embargo, para las matrices pequeñas para las que está diseñado el cv :: Matx, la asignación del montón sería muy costosa en comparación con hacer lo mismo en la pila. He visto un bloque de matemática reducir el tiempo de procesamiento en más del 75% al ​​cambiar al uso de tipos asignados a la pila (por ejemplo, cv :: Point y cv :: Matx) en lugar de cv :: Mat.

+1

Creo que el rendimiento también se obtiene mediante el desenrollado de bucles, lo que no se puede hacer para matrices de tamaño dinámico. – emu

7

Esta es una respuesta tarde tardía, pero sigue siendo una pregunta interesante!

La respuesta de dom es bastante precisa, y la referencia de montón/pila en user1460044 también es interesante.

Desde un punto de vista práctico, yo no usaríaMatx (o Vec), excepto si fuera completamente necesario. Las principales ventajas de Matx son

  1. Uso de la pila (eficiente! [1])
  2. inicialización.

El problema es que, al final, tendrá que mover sus datos a un MatxMat hacer la mayoría de las cosas, y por lo tanto, se le de vuelta a la pila de nuevo. Por otro lado, la "inicialización fresco" de un Matx se puede hacer en una estera de lo normal:

// Matx initialization: 
Matx31f A(1.f,2.f,3.f); 
// Mat initialization: 
Mat B = (Mat_<float>(3,1) << 1.f, 2.f, 3.f); 

Además, hay una diferencia en la inicialización (más allá de la pila pila /) cosas. Si intenta poner 5 valores en el Matx31, se bloqueará (excepción de tiempo de ejecución), mientras que al llamar al Mat_::operator<< con 5 valores solo se almacenarán los tres primeros.

[1] Eficiente si su programa tiene que crear muchas matrices de menos de ~ 10 elementos. En ese caso, use matrices Matx.

3

Hay otras 2 razones por las que prefiero Matx-Mat:

  1. legibilidad: la gente que lee el código pueden ver inmediatamente el tamaño de las matrices, por ejemplo:

    cv::Matx34d transform = ...; 
    

    está claro que esta es una matriz 3x4, por lo que contiene una transformación 3D de tipo (R, t), donde R es una matriz de rotación (en oposición a decir, eje-ángulo). Del mismo modo, acceder a un elemento es más natural con transform(i,j) frente a transform.at<double>(i,j).

  2. Depuración fácil. Dado que los elementos para Matx se asignan en la pila en una matriz de longitud conocida, los IDE o los depuradores pueden mostrar todos los contenidos correctamente al recorrer el código.