c++保存及读取文件

1.保存及读取单张图片

代码摘自 https://answers.opencv.org/question/6414/cvmat-serialization-to-binary-file/

代码中给出了两种方法,一种是opencv自带的FileStorage,另一种是使用c++原生的fstream实现。代码验证fstream方式更快。

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

int main()
{
    // Save the random generated data
    {
        Mat m(1024*256, 192, CV_8UC1);
        randu(m, 0, 1000);

        FileStorage fs("fs.yml", FileStorage::WRITE);
        fs << "m" << m;

        matwrite("raw.bin", m);
    }

    // Load the saved matrix

    {
        // Method 1: using FileStorage
        double tic = double(getTickCount());

        FileStorage fs("fs.yml", FileStorage::READ);
        Mat m1;
        fs["m"] >> m1;

        double toc = (double(getTickCount()) - tic) * 1000. / getTickFrequency();
        cout << "Using FileStorage: " << toc << endl; 
    }

    {
        // Method 2: usign raw binary data
        double tic = double(getTickCount());

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

        double toc = (double(getTickCount()) - tic) * 1000. / getTickFrequency();
        cout << "Using Raw: " << toc << endl;
    }

    int dummy;
    cin >> dummy;

    return 0;
}

2.保存及读取多张图片

void matwrite(const string& filename, vector<string>& imgFiles)
{
	ofstream fs(filename, fstream::binary);
	int num = imgFiles.size();
	fs.write((char*)&num, sizeof(int));    // img number


	for (auto& imgFile : imgFiles)
	{
		cout << imgFile << endl;
		cv::Mat mat = cv::imread(imgFile, -1);

		// Header
		//int nameLen = sizeof(char)* imgFile.size();
		int type = mat.type();
		int channels = mat.channels();

		//fs.write((char*)&nameLen, sizeof(int));    // name length
		fs << imgFile << std::endl;
		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);
		}

	}
	fs.close();
}

void  matread(const string& datName,map<string,cv::Mat>& matDic)
{
	ifstream fs(datName, fstream::binary);
	int num;
	fs.read((char*)&num, sizeof(int));         // img number

	for (int i = 0; i < num; i++)
	{
		// Header
		int nameLen,rows, cols, type, channels;
		string fileName="";

		//fs.read((char*)&nameLen, sizeof(int));         // rows
		//cout << "nameLen: " << nameLen << endl;

		getline(fs, fileName);
		cout << "fileName: " << fileName << endl;

		//fs.read((char*)&fileName, sizeof(char) * nameLen);     // 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
		cv::Mat mat(rows, cols, type);
		fs.read((char*)mat.data, CV_ELEM_SIZE(type) * rows * cols);

		matDic[fileName] = mat;

	}
	fs.close();
}

主程序为:

	string path = "./img";
	vector<string> imgFiles;
	getFiles(path, imgFiles);
	matwrite("mat.bin", imgFiles);
	map<string, cv::Mat> matDic;
	matread("mat.bin", matDic);

将图片保存为字典类型(图片名称+图片数据)。

参考文献

[1] https://answers.opencv.org/question/6414/cvmat-serialization-to-binary-file/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

外卖猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值