Efficiently load a large Mat into memory in OpenCV

匿名 (未验证) 提交于 2019-12-03 01:39:01

问题:

Is there a more efficient way to load a large Mat object into memory than the FileStorage method in OpenCV?

I have a large Mat with 192 columns and 1 million rows I want to store locally in a file and load into memory then my application starts. There is no problem using the FileStorage, but I was wondering if there exists a more efficient method to do this. At the moment it takes about 5 minutes to load the Mat into memory using the Debug mode in Visual Studio and around 3 minutes in the Release mode and the size of the data file is around 1.2GB.

Is the FileStorage method the only method available to do this task?

回答1:

Are you ok with a 100x speedup?


You should save and load your images in binary format. You can do that with the matwrite and matread function in the code below.

I tested both loading from a FileStorage and the binary file, and for a smaller image with 250K rows, 192 columns, type CV_8UC1 I got these results (time in ms):

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

On a image with 1M rows and 192 cols using the binary mode I got (time in ms):

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

NOTE

  1. Never measure performance in debug.
  2. 3 minutes to load a matrix seems way too much, even for FileStorages. However, you'll gain a lot switching to binary mode.

Here the code with the functions matwrite and matread, and the test:

#include  #include  #include   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(0), (mat.dataend - mat.datastart));     }     else     {         int rowsz = CV_ELEM_SIZE(type) * mat.cols;         for (int r = 0; r (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 > m1;          double toc = (double(getTickCount()) - tic) * 1000. / getTickFrequency();         cout > dummy;      return 0; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!