IplImage 结构的提升序列化问题
Issue with boost serialization of IplImage struct
我无法让 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);
}
我反序列化后得到的图像底部有像素噪声
序列化时:
反序列化时:
看来你图片的下半部分是随机记忆的。最有可能的是,char 数组的长度必须更长。
IplImage 支持 widthStep 大于 width*nChannels 的对齐数据。
您的计算只能处理没有对齐的 8 位图像。
使用 make_array 和 imageSize。
ar & boost::serialization::make_array<char>(frame->imageData, imageSize);
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
.[=18= 序列化它]
我无法让 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);
}
我反序列化后得到的图像底部有像素噪声
序列化时:
反序列化时:
看来你图片的下半部分是随机记忆的。最有可能的是,char 数组的长度必须更长。 IplImage 支持 widthStep 大于 width*nChannels 的对齐数据。 您的计算只能处理没有对齐的 8 位图像。
使用 make_array 和 imageSize。
ar & boost::serialization::make_array<char>(frame->imageData, imageSize);
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
.[=18= 序列化它]