c++ opencv mat opencv3.0

c++ - Cargue eficientemente un tapete grande en la memoria en OpenCV



mat opencv3.0 (1)

¿Estás bien con una aceleración de 100x ?

Debe guardar y cargar sus imágenes en formato binario. Puede hacerlo con la función matwrite y matread en el código a continuación.

FileStorage tanto la carga desde un FileStorage como el archivo binario, y para una imagen más pequeña con 250K filas, 192 columnas, escriba CV_8UC1 obtuve estos resultados (tiempo en ms):

// Mat: 250K rows, 192 cols, type CV_8UC1 Using FileStorage: 5523.45 Using Raw: 50.0879

En una imagen con 1M de filas y 192 cols usando el modo binario que obtuve (tiempo en ms):

// Mat: 1M rows, 192 cols, type CV_8UC1 Using FileStorage: (can''t load, out of memory) Using Raw: 197.381

NOTA

  1. Nunca mida el rendimiento en la depuración .
  2. 3 minutos para cargar una matriz parece demasiado, incluso para FileStorage s. Sin embargo, ganarás mucho cambiando al modo binario.

Aquí el código con las funciones matwrite y matread , y la prueba:

#include <opencv2/opencv.hpp> #include <iostream> #include <fstream> using namespace std; using namespace cv; void matwrite(const string& filename, const Mat& mat) { ofstream fs(filename, fstream::binary); // Header int type = mat.type(); int channels = mat.channels(); fs.write((char*)&mat.rows, sizeof(int)); // rows fs.write((char*)&mat.cols, sizeof(int)); // cols fs.write((char*)&type, sizeof(int)); // type fs.write((char*)&channels, sizeof(int)); // channels // Data if (mat.isContinuous()) { fs.write(mat.ptr<char>(0), (mat.dataend - mat.datastart)); } else { int rowsz = CV_ELEM_SIZE(type) * mat.cols; for (int r = 0; r < mat.rows; ++r) { fs.write(mat.ptr<char>(r), rowsz); } } } Mat matread(const string& filename) { ifstream fs(filename, fstream::binary); // Header int rows, cols, type, channels; fs.read((char*)&rows, sizeof(int)); // rows fs.read((char*)&cols, sizeof(int)); // cols fs.read((char*)&type, sizeof(int)); // type fs.read((char*)&channels, sizeof(int)); // channels // Data Mat mat(rows, cols, type); fs.read((char*)mat.data, CV_ELEM_SIZE(type) * rows * cols); return mat; } int main() { // Save the random generated data { Mat m(1024*256, 192, CV_8UC1); randu(m, 0, 1000); FileStorage fs("fs.yml", FileStorage::WRITE); fs << "m" << m; matwrite("raw.bin", m); } // Load the saved matrix { // Method 1: using FileStorage double tic = double(getTickCount()); FileStorage fs("fs.yml", FileStorage::READ); Mat m1; fs["m"] >> m1; double toc = (double(getTickCount()) - tic) * 1000. / getTickFrequency(); cout << "Using FileStorage: " << toc << endl; } { // Method 2: usign raw binary data double tic = double(getTickCount()); Mat m2 = matread("raw.bin"); double toc = (double(getTickCount()) - tic) * 1000. / getTickFrequency(); cout << "Using Raw: " << toc << endl; } int dummy; cin >> dummy; return 0; }

¿Existe una forma más eficiente de cargar un objeto Mat grande en la memoria que el método FileStorage en OpenCV?

Tengo un tapete grande con 192 columnas y 1 millón de filas que quiero almacenar localmente en un archivo y cargar en la memoria, luego se inicia mi aplicación. No hay ningún problema al usar FileStorage, pero me preguntaba si existe un método más eficiente para hacerlo. Por el momento, tarda unos 5 minutos en cargar el Mat en la memoria usando el modo de depuración en Visual Studio y alrededor de 3 minutos en el modo de lanzamiento y el tamaño del archivo de datos es de alrededor de 1,2 GB.

¿Es el método FileStorage el único método disponible para realizar esta tarea?