在标题中,我有std::vector<cv::Mat> matrices
我要写/读/从二进制文件。
现在,在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
个对象似乎有点棘手,并且在答案matRead
和matWrite
中完成了这项工作。所以我想知道如果不是上面的代码我应该做的事情:
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]
的大小作为偏移量附加。
我该怎么办?
更新
我提出了这个解决方案,用可选参数重写matWrite
和matRead
,以便在写入期间附加矩阵并开始从某一点开始读取:
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 :(得分:1)
如果Mat
代替单Mat
,您可以调整matread
and matwrite
的代码以用于向量。下面的函数vecmatread
和vecmatwrite
允许将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;
}
答案 1 :(得分:0)
我使用这个:
string name_1c;
ofstream outFile_1st;
name_1c = "m_scripts/labeled_1.bin";
outFile_1st.open(name_1c, std::ios::binary);
Mat data = Mat::zeros(100, 1024, CV_32FC);
vector<Mat> labeled_1(6);
// initialization of vector
for(int i = 0; i < 6; i ++)
labeled_1.push_back(randn(data, Scalar(128), Scalar(10)));
for (int i = 0; i < labeled_1.size(); i ++)
{
outFile_1st.write(reinterpret_cast<char*>(&labeled_1[i]), sizeof(float) * 100 * 1024);
}
outFile_1st.close();