c++opencvserializationboostiplimage

Issue with boost serialization of IplImage struct


I'm having trouble getting the boost serialization module to work with OpenCV's IplImage struct. Here is my code for serializing an IplImage (along with some JSON data in a custom struct)

    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
    }

Here is my code for deserializing the same struct

    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);
    }

The resulting image I obtain after deserializing has pixel noise at the bottom of the image

At serialization:

enter image description here

At deserialization:

enter image description here


Solution

  • Spambot analysis is correct, but there is more.

    To serialize you need to do something like

    for(int i = 0; i < height; ++i)
    {
       ar & boost::serialization::make_array<char>(
             frame->imageData+i*widthStep, 
             width * nChannels);
    }
    

    It saves only the visible portion of the buffer (the one you care about)

    to deserialize you also need to iterate over horizontal lines (strides) using the same formula.

    You can also convert to a cv::Mat with data copy enabled, which will give a real contiguous array of size width * height * nChannels and then serialize it with make_array.