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->widthStepframe->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= 序列化它]