2016-07-19 49 views
0

die Frage Follow-up here von Serialisierung OpenCV Mat_Merge mehrere Boost-serialisierten OpenCV Mats

Meine Aufgabe ist es ich mehrere OpenCV Mats haben, die serialisiert werden. Jetzt möchte ich all diese Mats zusammenführen. Ich kann dies tun, indem Sie diese Binärdateien in Mats deserialisieren und die Methode push_back verwenden, um sie zusammenzuführen. Aus meinem eigenen Grund muss ich sie jedoch zuerst im Binärformat zusammenführen, bevor sie deserialisiert werden.

Wie kann ich diese Binärdateien zusammenführen, damit ich am Ende meine Deserialisierung aufrufen kann, um die ganze große Matte zu bekommen?

Dank

Antwort

1

Sie können dies tun, ohne Schub zu verwenden. Nach dem beschriebenen Serialisierungsansatz here können Sie die Daten Ihrer Matrix am Ende der Datei anhängen, wobei Sie darauf achten, die Anzahl der Zeilen der endgültigen Matrix entsprechend zu erhöhen.

Hier ist ein Arbeitsbeispiel, wo matappend die Arbeit erledigt. Ich werde auch die matread und matwrite Funktionen für die Vollständigkeit:

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

void matappend(const string& filename, const Mat& mat) 
{ 
    fstream fs(filename, fstream::binary | fstream::in); 

    // https://stackoverflow.com/a/2390938/5008845 
    if (fs.peek() == fstream::traits_type::eof()) 
    { 
     // The file is empty, write (same as matwrite) 

     fs.close(); 
     fs.open(filename, fstream::binary | fstream::out); 

     // 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 
    } 
    else 
    { 
     // The file is not empty, append 

     fs.close(); 
     fs.open(filename, fstream::binary | fstream::out | fstream::in); 

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

     // Consistency check 
     CV_Assert((cols == mat.cols) && (type == mat.type()) && (channels == mat.channels())); 

     // Go to beginning of file 
     fs.seekp(fstream::beg); 

     // Overwrite the number of rows 
     rows += mat.rows; 
     fs.write((char*)&rows, sizeof(int)); // rows 

     // Go to end of file 
     fs.seekp(0, fstream::end); 
    } 

    // Write data 
    if (mat.isContinuous()) 
    { 
     fs.write(mat.ptr<char>(0), (mat.dataend - mat.datastart)); 
    } 
    else 
    { 
     int rowsz = CV_ELEM_SIZE(mat.type()) * mat.cols; 
     for (int r = 0; r < mat.rows; ++r) 
     { 
      fs.write(mat.ptr<char>(r), rowsz); 
     } 
    } 
    fs.close(); 
} 



int main() 
{ 
    // Save the random generated data 

    Mat1b m1 = (Mat1b(2, 2) << 1, 2, 3, 4); 
    Mat1b m2 = (Mat1b(3, 2) << 5, 6, 7, 8, 9, 10); 

    matappend("raw.bin", m1); 
    matappend("raw.bin", m2); 

    Mat m3 = matread("raw.bin"); 

    // m3: 
    // 1 2 
    // 3 4 
    // 5 6 
    // 7 8 
    // 9 10 


    return 0; 
}