2016-12-17 2 views
1

Wie im Titel, ich habe std::vector<cv::Mat> matrices, die ich schreiben/lesen zu/von Binärdatei.Schreiben Sie einen Vektor von cv :: Mat in Binärdatei in C++

Jetzt, nach this Antwort, alles, was ich für das Schreiben tun sollte, ist, ist:

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(); 

jedoch folgende this Antwort scheint cv::Mat Objekte zu schreiben ein wenig kompliziert, und in der Antwort matRead und matWrite das tun Job. So frage ich mich, wenn anstelle des obigen Code ich etwas tun sollte wie:

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]); 

jedoch nicht dieser Code nicht funktionieren, da matWrite() überschreibt matrices.bin bei jedem Zyklus, also sollte ich die Größe von matrices[i] hängen als Offset vor dem Schreiben Matrix selbst.

Was soll ich tun?

UPDATE:

ich mit dieser Lösung kam, matWrite und matRead mit optionalen Argumenten Umschreiben für Matrizen beim Schreiben und Start Anfügen von einem bestimmten Punkt zu lesen:

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

und Funktionen Angerufen mit:

//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

Ich bin wirklich neugierig zu wissen, warum jemand mir eine downvote für diesen questio – justHelloWorld

+0

auf dem Duplikat Einen Hinweis gab. Sie können durch jede Matrix in Ihrem Vektor iterieren und "matappend" verwenden. – Miki

+0

Wenn das Duplikat nicht hilft, lass es mich wissen. Aber jetzt sollten Sie in der Lage sein, eine korrekte Funktion selbst zu schreiben – Miki

Antwort

1

Sie können den Code anpassen von matread and matwrite mit Vektoren zu verwenden, wenn Mat anstelle von Mat. Die Funktionen vecmatread und vecmatwrite unten ermöglichen ein std::vector<cv::Mat> in eine Datei zu schreiben und lesen Sie den Vektor zurück:

#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; 
} 
Verwandte Themen