我无法使用boost序列化模块来使用OpenCV的IplImage结构。 这是我的序列化IplImage的代码(以及自定义结构中的一些JSON数据)
template <class Archive>
void save(Archive & ar, const unsigned int version) const
{
// First things first; save the essential variables
// These are needed as input to the create function of IplImage
ar & frame->width;
ar & frame->height;
ar & frame->depth;
ar & frame->nChannels;
ar & frame->widthStep;
ar & frame->imageSize;
// ar & frame->nSize;
// ar & frame->ID;
// ar & frame->dataOrder;
// ar & frame->origin;
// ar & frame->align;
// ar & frame->widthStep;
// ar & frame->imageSize;
// Then save the actual image data
ar & boost::serialization::make_array<char>(frame->imageData, (frame->width * frame->height * frame->nChannels) + 1);
std::string metaString = meta.dump();
ar & metaString; // ...and don't forget the meta data
}
这是我反序列化相同结构的代码
template <class Archive>
void load(Archive & ar, const unsigned int version)
{
int width;
int height;
int depth;
int nChannels;
int widthStep;
int imageSize;
ar & width;
ar & height;
ar & depth;
ar & nChannels;
ar & widthStep;
ar & imageSize;
// Create the image header with this knowledge
frame = cvCreateImage(cvSize(width, height), depth, nChannels);
frame->widthStep = widthStep;
frame->imageSize = imageSize;
// And grab the rest of the data
// ar & frame->nSize;
// ar & frame->ID;
// ar & frame->dataOrder;
// ar & frame->origin;
// ar & frame->align;
// ar & frame->widthStep;
// ar & frame->imageSize;
// Now we have all the variables, we can load the actual image data
ar & boost::serialization::make_array<char>(frame->imageData, (width * height * nChannels) + 1);
// Deserialize the json data
std::string metaString;
ar & metaString;
meta = json(metaString);
}
反序列化后得到的结果图像在图像底部有像素噪声
序列化:
反序列化:
答案 0 :(得分:1)
Spambot分析是正确的,但还有更多。
frame->imageData
。因此,行的最后一个像素与下一行(frame->imageData - frame->imageDataOrigin)
的第一个像素之间存在间隙frame->widthStep
和frame->imageSize
是仅在给定特定对齐时才有意义的值。他们不应设置,并且对于使用cvCreateImage
要序列化,您需要执行类似
的操作for(int i = 0; i < height; ++i)
{
ar & boost::serialization::make_array<char>(
frame->imageData+i*widthStep,
width * nChannels);
}
它只保存缓冲区的可见部分(你关心的那个)
要反序列化你还需要使用相同的公式迭代水平线(步幅)。
您还可以在启用数据复制的情况下转换为cv :: Mat,这将提供一个大小为width * height * nChannels
的实际连续数组,然后使用make_array
对其进行序列化。
答案 1 :(得分:0)
图像的下半部分似乎是随机记忆。最有可能的是,char数组的长度必须更长。 IplImage支持对齐数据,其中widthStep大于width * nChannels。 您的计算只能在没有对齐的情况下处理8Bit图像。
将make_array与imageSize一起使用。
ar & boost::serialization::make_array<char>(frame->imageData, imageSize);