Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

FileStorage and (smart) pointers

Hi,

I've created a class Image which is a wrapper over a Mat (the actual data), plus some keypoints, descriptors, camera intrinsic matrix, etc .. I have an Image::ptr which is a shared_ptr<image>

I have vectors of Image::ptr, pairs of Image::ptr. Everybody is sharing, everything is great!

Up until I serialize // deserialize them using FileStorage.

Not surprisingly the serialized file contains a copy of the data, in every place I've used an Image::ptr. The more problematic thing, is that if I de-serialize I now have a copy of my Image everytime it appeared in a vector. (I don't serialize the actual pixels, just descriptors but still).

The question is, Is there a way to deal with smart / auto ptr to avoid redundancy when serializing ?

Otherwise, I'm considering using a global variable holding a map<index,image::ptr> and then replace Image::ptr with index everywhere. Or is there a simpler cleaner way that I haven't seen ?

Thank you!

FileStorage and (smart) pointers

Hi,

I've created a class Image which is a wrapper over a Mat (the actual data), plus some keypoints, descriptors, camera intrinsic matrix, etc .. I have an Image::ptr which is a shared_ptr<image>

I have vectors of Image::ptr, pairs of Image::ptr. Everybody is sharing, everything is great!

Up until I serialize // deserialize them using FileStorage.

Not surprisingly the serialized file contains a copy of the data, in every place I've used an Image::ptr. The more problematic thing, is that if I de-serialize I now have a copy of my Image everytime it appeared in a vector. (I don't serialize the actual pixels, just descriptors but still).

The question is, Is there a way to deal with smart / auto ptr to avoid redundancy when serializing ?

Otherwise, I'm considering using a global variable holding a map<index,image::ptr> and then replace Image::ptr with index everywhere. Or is there a simpler cleaner way that I haven't seen ?

Thank you!

EDIT: adding code snippet

class Image {
  typedef shared_ptr<Image> ptr;

  Mat data;
  vector<Keypoint> Keypoints;
  Mat descriptors;
}

Image::ptr img1 (new Image());
Image::ptr img2 (new Image());

pair<Image::ptr, Image::ptr>> image_matches1;
pair<Image::ptr, Image::ptr>> image_matches2;

// note that it's the same pair
image_matches1 = make_pair(img1, im2);
image_matches2 = make_pair(img2, im1);

// prints out the same pointer, which makes sense
cout << image_matches1.first() << endl;
cout << image_matches2.second() << endl;

// serialization
FileStorage fsb("filestorage_pairs.txt", FileStorage::WRITE);
 fsb << "pair1" << img_matches1;
 fsb << "pair2" << img_matches2;
 fsb.release();

// de-serialization
fsb.open("filestorage_pairs.txt", FileStorage::READ);

ImagePair pair1_loaded;
ImagePair pair2_loaded;

 fsb["pair1"] >> pair1_loaded;
 fsb["pair2"] >> pair2_loaded;

// now the pointers are different, through serializaion / deserialization the resource has been copied
cout << pair1_loaded.first() << end;
cout << pair2_loaded.second() << end;