2016-12-17 78 views
1

在標題中,我有要寫入/讀取到/從二進制文件中讀取的std::vector<cv::Mat> matrices在C++中編寫cv :: Mat到二進制文件的矢量

現在,隨着this答案,都是我應該做的是寫的是:

ofstream fout("matrices.bin", ios::out | ios::binary); 
size_t size = matrices.size(); 
fout.write((char*)&size, sizeof(size)); 
fout.write((char*)&matrices[0], v.size() * sizeof(cv::Mat)); 
fout.close(); 

然而,以下this答案,寫cv::Mat對象似乎有點棘手,並在回答matReadmatWrite做工作。所以我想,如果不是上面的代碼,我應該這樣做:

ofstream fout("matrices.bin", ios::out | ios::binary); 
size_t size = matrices.size(); 
fout.write((char*)&size, sizeof(size)); 
for(size_t i = 0 ; i < matrices.size() ; i++) 
    matWrite("matrices.bin", matrices[i]); 

但是這個代碼不工作,因爲matWrite()在每個週期覆蓋matrices.bin,所以我應該追加的matrices[i]大小爲寫前偏移矩陣本身。

我該怎麼辦?

UPDATE:

我想出了這個解決方案,改寫matWritematRead與可選參數寫入和啓動從某一個點讀期間追加矩陣:

void matwrite(const std::string& filename, const cv::Mat& mat, const bool append = false) { 

    std::ofstream fs; 
    if(append) 
     fs.open(filename.c_str(), std::fstream::binary | std::fstream::app); 
    else 
     fs.open(filename.c_str(), std::fstream::binary); 

//the rest of matwrite is the same... 

} 

cv::Mat matRead(const std::string& filename, size_t &offset = 0) 
{ 
    std::ifstream fs(filename, std::fstream::binary); 
    fs.seekg(offset); 
    ... 
    offset += 4 * sizeof(int) + CV_ELEM_SIZE(type) * rows * cols; //update offset //move offset of 4 ints and mat size 
    return mat; 
} 

和功能稱爲:

//writing: 
for(size_t i = 0 ; i<v.size() ; i++) 
    writemat(filename, v[i], true); 
//reading: 
size_t offset = 0; 
for(size_t i = 0 ; i<size ; i++){ // size = v.size() during writing 
    cv::Mat mat = matRead(filename, offset); 
    v.push_back(mat); 
} 
+0

我真的很好奇,想知道爲什麼有人給了我一個downvote這個questio – justHelloWorld

+0

了一份關於重複。您可以遍歷矢量中的每個矩陣,並使用「matappend」。 – Miki

+0

如果重複不起作用,請告訴我。但是,現在你應該能夠自己寫一個正確的功能 – Miki

回答

1

您可以調整代碼matread and matwriteMat一起使用,而不是單個的Mat。下面的功能vecmatreadvecmatwrite允許寫std::vector<cv::Mat>到一個文件,並宣讀了矢量回:

#include <opencv2\opencv.hpp> 
#include <vector> 
#include <iostream> 
#include <fstream> 

using namespace std; 
using namespace cv; 

void vecmatwrite(const string& filename, const vector<Mat>& matrices) 
{ 
    ofstream fs(filename, fstream::binary); 

    for (size_t i = 0; i < matrices.size(); ++i) 
    { 
     const Mat& mat = matrices[i]; 

     // 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); 
      } 
     } 
    } 
} 

vector<Mat> vecmatread(const string& filename) 
{ 
    vector<Mat> matrices; 
    ifstream fs(filename, fstream::binary); 

    // Get length of file 
    fs.seekg(0, fs.end); 
    int length = fs.tellg(); 
    fs.seekg(0, fs.beg); 

    while (fs.tellg() < length) 
    { 
     // 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); 

     matrices.push_back(mat); 
    } 
    return matrices; 
} 


int main() 
{ 
    vector<Mat> matrices; 

    // Fill vector... 
    Mat1f m1(3,3); 
    randu(m1, 0, 1); 

    Mat3b m2(4, 5); 
    randu(m2, Scalar(0,0,0), Scalar(256,256,256)); 

    Mat2d m3(2, 3); 
    randu(m3, Scalar(0, 0), Scalar(1, 1)); 

    matrices.push_back(m1); 
    matrices.push_back(m2); 
    matrices.push_back(m3); 

    // Write the vector to file 
    vecmatwrite("test.bin", matrices); 

    // Read the vector from file 
    vector<Mat> matrices2 = vecmatread("test.bin"); 

    return 0; 
} 
相關問題