I'm working on a robotics research project where I need to serialize 2D matrices of 3D points: basically each pixel is a 3-vector of floats. These pixels are saved in an OpenCV matrix, and they need to be sent over inter-process communication and saved into files to be processed on multiple computers. I'd like to serialize them in an endian/architecture-independent, space-efficient way, as quickly as possible. cv::imencode
here would be perfect, except that it only works on 8-bit and 16-bit elements, and we don't want to lose any precision. The files don't need to be human-readable (although we do that now to ensure data portability, and it's incredibly slow). Are there best practices for this, or elegant ways to do it?
Thanks!
I was recently asking myself a similar question, though specifically I was trying to serialize opencv's
Mat
andMatND
objects. Usingboost::serialize
is nice, but requires a couple tricks. As you don't want to go about modifying the internals of OpenCV itself to serialize these objects, you are forced to use what's called a "free" function. Since it is complicated to serialize the OpenCV objects, I found I was forced to split the serialize operation into save and load, each with a slightly different implementation. You need to useboost/serialization/split_free.hpp
for this task. Boost provides good documentation for this here: http://www.boost.org/doc/libs/1_45_0/libs/serialization/doc/index.html.Good luck!
Edit: Christoph Heindl has commented on this post with a link to his blog where he has improved on this serialisation code. Highly recommended!
http://cheind.wordpress.com/2011/12/06/serialization-of-cvmat-objects-using-boost/
--
For whoever it may benefit: Some code to serialize Mat& with boost::serialization
I haven't tested with multi-channel data, but everything should work fine.
Now, mat can be serialized and deserialized as following:
I've used the binary_oarchive and binary_iarchive here to keep the memory usage down. The binary format doesn't provide portability between platforms, but if desired the text_oarchive/iarchive can be used.
The earlier answers are good, but they won't work for non-continuous matrices which arise when you want to serialize regions of interest (among other things). Also, it is unnecessary to serialize
elemSize()
because this is derived from thetype
value.Here's some code that will work regardless of continuity (with includes/namespace)
You can use msgpack also Create an adaptor https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Here is example code. It might be useful:
You could use
boost::serialization
for that. It's heavily optimized and is pretty easy to integrate.Possible speed-ups for your case include serializing each object as a raw binary block (see
boost::serialization::make_binary
) and disabling version tracking (BOOST_SERIALIZATION_DISABLE_TRACKING
).Also, you can experiment with adding compression into your serialization routines to save space (and time in case of data that is easily compressable). This can be implemented with
boost::iostreams
, for example.I wrote this code: