要使用 Google Protocol Buffers 序列化 OpenCV 矩阵,可以使用 FileStorage 类从 OpenCV 中可用的 XML/YAML/JSON 序列化中获得灵感。所需的所有信息是行数、列数、元素类型、元素大小和矩阵的原始数据。
这是 .proto 定义:
syntax = "proto3";
package opencv;
message OcvMat {
int32 rows = 1;
int32 cols = 2;
int32 elt_type = 3;
int32 elt_size = 4;
bytes mat_data = 5;
}
Run Code Online (Sandbox Code Playgroud)
这是 C++ 中的序列化代码,假设我们要将矩阵保存在一个仅包含此数据的文件中:
cv::Mat m = cv::Mat::ones(480, 640, CV_8UC3);
//open a file in output, overwrite and binary mode
fstream output("path/to/file.extention", ios::out | ios::trunc | ios::binary);
//create an instance of the class generated by the compilation of the .proto file
opencv::OcvMat serializableMat;
//set the trivial fields
serializableMat.set_rows(m.rows);
serializableMat.set_cols(m.cols);
serializableMat.set_elt_type(m.type());
serializableMat.set_elt_size((int)m.elemSize());
//set the matrix's raw data
size_t dataSize = m.rows * m.cols * m.elemSize();
serializableMat.set_mat_data(m.data, dataSize);
//write to file
if(!serializableMat.SerializeToOstream(&output))
{
cerr << "error" << endl;
}
output.close();
Run Code Online (Sandbox Code Playgroud)
这是 C++ 中的反序列化代码:
//open the file where the data was written in input and binary mode
fstream input("path/to/file.extension", ios::in | ios::binary);
//create an instance of the class generated automatically by the compilation of the .proto file
opencv::OcvMat serializableMat;
//create an empty OpenCV matrix
cv::Mat m;
//read the data from the input file into the OcvMat object
if(serializableMat.ParseFromIstream(&input))
{
//allocate the matrix
m.create(serializableMat.rows(),
serializableMat.cols(),
serializableMat.elt_type());
//set the matrix's data
size_t dataSize = serializableMat.rows() * serializableMat.cols() * serializableMat.elt_size();
std::copy(reinterpret_cast<unsigned char *>(
const_cast<char *>(serializableMat.mat_data().data())),
reinterpret_cast<unsigned char *>(
const_cast<char *>(serializableMat.mat_data().data()) + dataSize),
m.data);
}
else
{
cerr << "error" << endl;
}
input.close();
Run Code Online (Sandbox Code Playgroud)
然后可以将 OpenCV 矩阵序列化为更复杂的序列化对象的属性。序列化的唯一区别是必须将数据设置为指向使用访问的 OcvMat 对象的指针
myComplexObject.mutable_field_name()
Run Code Online (Sandbox Code Playgroud)
,其中“filed_name”是指定给 OcvMat 类型字段的名称。对于反序列化,它将完全相同。反序列化的复杂对象中包含的 OcvMat 对象通过调用访问
myComplexObject.field_name().
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2588 次 |
| 最近记录: |