Ask Your Question
0

why serialized vector of Mat won't work?

asked Jun 26 '18

azdoud.y gravatar image

updated Jun 26 '18

hello,

I've written this code which opens tree images and push them with some infos inside vector<ColletorMat> setFrames then I save this vector of Mat within a binary file. so as to load it later and open these images again. however, I didn't get the aim

any will be appreciated

#include <opencv2\opencv.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include "opencv2/core/core.hpp"

#include <iostream>
#include <fstream>

using namespace std;
using namespace cv;

class ColletorMat
{
private:
    int indexFrame;
    bool found;
    Mat frame;

public:

    ColletorMat(int index, bool found, Mat frame)
    {
        this->indexFrame = index;
        this->found = found;
        this->frame = frame;
    }

    ~ColletorMat()
    {

    }

    // settors
    void set_indexFrame(int index)
    {
        this->indexFrame = index;
    }

    void set_found(bool found)
    {
        this->found = found;
    }

    void set_frame(Mat frame)
    {
        this->frame = frame;
    }

    // accessors
    int get_indexFrame()
    {
        return this->indexFrame;
    }

    bool get_found()
    {
        return this->found;
    }

    Mat get_frame()
    {
        return this->frame;
    }

};

int main()
{

    {
        Mat image1, image2, image3;
        image1 = imread("C:\\opencvVid\\data_seq\\Human3\\0001.jpg");
        image2 = imread("C:\\opencvVid\\data_seq\\Human3\\0002.jpg");
        image3 = imread("C:\\opencvVid\\data_seq\\Human3\\0003.jpg");

        if (image1.empty() || image2.empty() || image3.empty()) {
            std::cout << "error: image not readed from file\n";
            return(0);
        }

        imshow("M1",image1);
        imshow("M2",image2);
        imshow("M3",image3);

        (char)cvWaitKey(0);

        vector<ColletorMat> setFrames;

        ColletorMat colletorMat1(1,false,image1.clone());
        ColletorMat colletorMat2(1,false,image2.clone());
        ColletorMat colletorMat3(1,false,image3.clone());

        setFrames.push_back(colletorMat1);
        setFrames.push_back(colletorMat2);
        setFrames.push_back(colletorMat3);

        ofstream fs("setFrms.bin", fstream::binary);

        fs.write((char *) &setFrames, sizeof(vector<ColletorMat>));
        fs.close();

        ifstream loadFs("setFrms.bin", ios::binary);

        if(!loadFs.is_open()){
            cout << "error while opening the binary file" << endl;
        }

        vector<ColletorMat> setFramesLoad;

        loadFs.read( (char *) &setFramesLoad, sizeof(vector<ColletorMat>));
        cout << "frames loaded up " << setFramesLoad.size() << endl;

        imshow("1",setFramesLoad.at(0).get_frame());
        imshow("2",setFramesLoad.at(1).get_frame());
        imshow("3",setFramesLoad.at(2).get_frame());

        loadFs.close();

    }

    return 0;
}
Preview: (hide)

Comments

How about encapsulating the images in a class and serializing / deserializing within the constructor?

holger gravatar imageholger (Jun 26 '18)edit

I serialized each object alone, then I deserialized each object respectively next I push them in that vector.

azdoud.y gravatar imageazdoud.y (Jun 26 '18)edit

hmm what i can tell you that with the mat clas its all ok: serializing:

imwrite(path)

deserializing

imread(path)

is working, the rest is in you code and not really related to opencv. My c++ knowledge is limited so i cannot really help. I assume your problem is in line

loadFs.read( (char *) &setFramesLoad, sizeof(vector<ColletorMat>));

Try to use vector<mat> and read / write from it.

holger gravatar imageholger (Jun 26 '18)edit

I did this code it does the aim, thank you

azdoud.y gravatar imageazdoud.y (Jun 26 '18)edit

ok - great to hear its working for you :-) Could you close your question as closed then?

holger gravatar imageholger (Jun 26 '18)edit

1 answer

Sort by » oldest newest most voted
1

answered Jun 26 '18

azdoud.y gravatar image

serializing each object alone, then I deserializing each object respectively by adding these functions

void matwrite(ofstream& fs, const Mat& mat, int index, bool checking){

    // Data Object
    int indexFrame = index;
    bool found = checking;
    fs.write((char*)&indexFrame, sizeof(int));    // indexFrame
    fs.write((char*)&found, sizeof(bool));    // bool checking

    // Header
    int type = mat.type();
    int channels = mat.channels();
    fs.write((char*)&mat.rows, sizeof(int));    // rows
    fs.write((char*)&mat.cols, sizeof(int));    // cols
    fs.write((char*)&type, sizeof(int));        // type
    fs.write((char*)&channels, sizeof(int));    // channels

    // Data
    if (mat.isContinuous())
    {
        fs.write(mat.ptr<char>(0), (mat.dataend - mat.datastart));
    }
    else
    {
        int rowsz = CV_ELEM_SIZE(type) * mat.cols;
        for (int r = 0; r < mat.rows; ++r)
        {
            fs.write(mat.ptr<char>(r), rowsz);
        }
    }
}   

ColletorMat matread(ifstream& fs){

    // Data Object
    int indexFrame;
    bool found;
    fs.read((char*)&indexFrame, sizeof(int));     //
    fs.read((char*)&found, sizeof(bool));         //

    // Header
    int rows, cols, type, channels;
    fs.read((char*)&rows, sizeof(int));         // rows
    fs.read((char*)&cols, sizeof(int));         // cols
    fs.read((char*)&type, sizeof(int));         // type
    fs.read((char*)&channels, sizeof(int));     // channels

    // Data
    Mat mat(rows, cols, type);
    fs.read((char*)mat.data, CV_ELEM_SIZE(type) * rows * cols);

    ColletorMat ojbectMat(indexFrame, found, mat);
    return ojbectMat;
}
Preview: (hide)

Question Tools

1 follower

Stats

Asked: Jun 26 '18

Seen: 585 times

Last updated: Jun 26 '18