有一个温和的解决方案吗? (例如现有的Mat.proto文件。)
答案 0 :(得分:2)
要使用Google协议缓冲区序列化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;
}
这是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();
这是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();
然后可以将OpenCV矩阵序列化为更复杂的序列化对象的属性。序列化的唯一区别是必须将数据设置为指向使用
访问的OcvMat对象的指针 myComplexObject.mutable_field_name()
,其中“ filed_name”是为OcvMat类型的字段指定的名称。对于反序列化,它将完全相同。通过调用来访问反序列化复杂对象中包含的OcvMat对象
myComplexObject.field_name().
答案 1 :(得分:1)
那是一个棘手的问题。问题是您是否需要cv :: Mat的所有数据和属性?如果是的话,我表示慰问,因为您需要将所有内容映射到新的protobuf结构。
如果您想要这样的东西:
// make a 7x7 complex matrix filled with 1+3j.
Mat M(7,7,CV_32FC2,Scalar(1,3));
您需要以下内容:
message Mat {
required uint32 xSize = 1; //7
required uint32 ySize = 2; //7
required string encoding = 3; //CV_32FC2
message Scalar { // this is optional
required uint32 x = 1;
required uint32 y = 2;
required uint32 z = 3;
}
repeated Scalar matrix = 4; // 49 elements
//note here that the Scalar is a 4-element vector derived from Vec
//and the matrix should consist of scalars
}