【问题标题】:Merge several boost serialized OpenCV Mats合并几个 boost 序列化的 OpenCV Mats
【发布时间】:2016-11-22 23:22:51
【问题描述】:

跟进 Serializing OpenCV Mat_ 的问题here

我的任务是我有多个序列化的 OpenCV Mats。现在我想合并所有这些垫子。我可以通过将这些二进制文件反序列化为 Mats 并使用 push_back 方法合并它们来做到这一点。但是,出于我自己的原因,我必须先将它们合并为二进制格式,然后再进行反序列化。

如何合并这些二进制文件,以便最终调用相同的反序列化来获得整个大 Mat?

谢谢

【问题讨论】:

    标签: c++ opencv serialization boost mat


    【解决方案1】:

    您可以在不使用 boost 的情况下做到这一点。按照here 描述的序列化方法,您可以将矩阵的数据附加到文件末尾,并相应地增加最终矩阵的行数。

    这是一个工作示例,matappend 完成了这项工作。为了完整起见,我还将添加 matreadmatwrite 函数:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多