2012-06-13 11 views
13

Soy nuevo en opencv y tengo una duda con una de las operaciones más sencillas de codificación: Pasar valores a funciones.Paso simple de matrices, es decir. cv :: Mat para funciones en OpenCV2.4

Esto es lo que quiero hacer,

  1. Iniciar una cv:Mat en la función main con, por ejemplo, los valores de 0 a 50.
  2. Pasar esta matriz como argumento a una función foo() que a su vez simplemente imprime los valores de cada elemento en la matriz. Eso es.

Ahora he leído en varios lugares que cuando se pasan estas matrices, solo se pasa el encabezado, no los datos reales. Entonces, ¿cómo puedo leer los valores de esta matriz en la función llamada como si se hubiera pasado toda la matriz?

+0

¿Dónde están estos lugares? ¿Puedes compartir referencias a ellos? – karlphillip

+0

http://opencv.willowgarage.com/documentation/cpp/memory_management.html –

Respuesta

31

Para entender lo que está pasando que necesita para echar un vistazo a C++ constructors, más específicamente la copy constructor.

Cuando se crea un cv::Matcv::Mat de otro, como en:

cv::Mat a = cv::imread("huge.png", 1); 
cv::Mat b = a; 

la constructor de copia (que es una función) de cv::Mat está llamada a realizar la copia del objeto. Antes de hablar sobre lo que sucede en el procedimiento de copia, debe tener en cuenta que, como se usa cv::Mat para almacenar imágenes, las imágenes más grandes pueden ocupar cientos de megabytes en la memoria. Entonces, ¿qué hace el copia constructor de cv::Mat en el ejemplo anterior es copiar el encabezado completo (altura, ancho, información de profundidad y otros) de a en b, pero en lugar de copiar los datos completos/píxeles de a (que podrían ser cientos de MB), simplemente apunta (usando un puntero) a los datos originales de a.

En otras palabras, no copiando toda la información de la imagen es una decisión de optimización/rendimiento.

Ahora, consideremos el código que llama a una función y pasa cv::Mat como parámetro:

void do_something(cv::Mat src) 
{ 
    // changing src pixels will be the same as changing orig pixels 
} 

int main() 
{ 
    cv::Mat orig = cv::imread("huge.png", 1); 
    do_something(orig); 
    return 0; 
} 

Si usted ha estudiado cómo pasar parámetros a funciones, ustedes saben que llamar do_something(a); se pass the parameter by value. Esto significa que intentará copiar el contenido de orig en src, sin embargo, este procedimiento activa el constructor de copia de cv::Mat que no hará una copia impresa de los datos como acabo de explicar.

¿Solución a este problema? Si está escribiendo do_something() y lo que desea hacer una copia real de orig, basta con crear una nueva cv::Mat y llame al método copyTo():

void do_something(cv::Mat src) 
{ 
    cv::Mat real_copy = src.copyTo(); 
    // operating on the data of real_copy will not affect orig 
} 

Pero recuerda, si src es ~ 100 MB llamando copyTo() para hacer la copia verdadera ocupará otros ~ 100MB de memoria, lo que significa que en una llamada de función única su programa pasó de 100MB a 200MB.Tenga esto en cuenta al diseñar su sistema. Buena suerte.

+4

Excelente. Es como si leyeras mi mente y respondieras la pregunta exacta que tenía. Muchas gracias señor. Muy apreciado. –

+1

Genial, solo haga clic en la casilla de verificación cercana para seleccionarla como la respuesta oficial. – karlphillip

Cuestiones relacionadas