0
跟進序列化的OpenCV Mat_合併幾個升壓系列化的OpenCV墊
我的任務問題here是我有多個OpenCV的墊是序列化。現在我想合併所有的墊子。我可以通過將這些二進制文件反序列化爲Mats並使用push_back
方法來合併它們。但是,出於我自己的原因,我必須在反序列化之前先以二進制格式合併它們。
如何合併這些二進制文件,以便最終可以調用相同的反序列化來獲取整個大的文件?
感謝
跟進序列化的OpenCV Mat_合併幾個升壓系列化的OpenCV墊
我的任務問題here是我有多個OpenCV的墊是序列化。現在我想合併所有的墊子。我可以通過將這些二進制文件反序列化爲Mats並使用push_back
方法來合併它們。但是,出於我自己的原因,我必須在反序列化之前先以二進制格式合併它們。
如何合併這些二進制文件,以便最終可以調用相同的反序列化來獲取整個大的文件?
感謝
你可以做到這一點,而無需使用提升。按照here描述的序列化方法,您可以在文件末尾添加矩陣的數據,從而相應地增加最終矩陣的行數。
下面是一個工作示例,其中matappend
完成這項工作。我也會把matread
和matwrite
功能完整性:
#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;
}