cv::Mat
cereal不直接支持cv::Mat类型的数据结构,但是可以通过自己设计的结构体,进行序列化数据存储和读取。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <cereal/archives/binary.hpp>
#include <cereal/types/vector.hpp>
#include <fstream>
struct imgInfo{
int32_t imgWidth;
int32_t imgHeight;
int32_t imgChannel;
int32_t imgType;
std::vector<uint8_t> imgData;
//结构体中必须包含serialize函数才能使用cereal进行序列化
template<class Archive>
void serialize(Archive & archive){
archive(imgWidth, imgHeight, imgChannel, imgType, imgData);
}
};
void main(){
cv::Mat testImg = cv::imread("/Users/Downloads/test.jpeg");
testInfo outInfo;
outInfo.imgWidth = testImg.cols;
outInfo.imgHeight = testImg.rows;
outInfo.imgChannel = testImg.channels();
outInfo.imgType = testImg.type();
if (testImg.isContinuous()) {
outInfo.imgData.assign(testImg.data, testImg.data + testImg.total()*testImg.channels());
} else {
for (int i = 0; i < testImg.rows; ++i){
outInfo.imgData.insert(outInfo.imgData.end(), testImg.ptr<uchar>(i), testImg.ptr<uchar>(i)+testImg.cols*testImg.channels());
}
}
//存储二进制图像数据
{
std::ofstream os("out.lut", std::ios::out | std::ios::binary);
cereal::BinaryOutputArchive archive(os);
archive(outInfo);
}
//读取二进制图像数据
testInfo inInfo;
{
std::ifstream intest("out.lut", std::ios::in | std::ios::binary);
cereal::BinaryInputArchive iarchive(intest);
iarchive(inInfo);
}
cv::Mat inImg= cv::Mat{inInfo.imgWidth, inInfo.imgHeight, inInfo.imgType,inInfo.imgData.data()};
}
Tips:
- mat.isContinuous返回矩阵元素在内存中是否连续存储。如果图像数据在每行末尾是没有间隙连续存储的,则方法返回true。一般经过裁剪或截取的mat图像不是连续存储的。
- 出现错误:
error: static_assert failed due to requirement 'traits::detail::count_output_serializers<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, cereal::BinaryOutputArchive>::value != 0' "cereal could not find any output serialization functions for the provided type and archive combination. \n\n Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these).
解决方法:添加#include <cereal/types/vector.hpp>
。序列化vector时需要添加相应的头文件。序列化其他数据类型时,需要添加其他相应的头文件。
参考资料
- https://uscilab.github.io/cereal/quickstart.html