steven-varga / h5cpp

C++17 templates between [stl::vector | armadillo | eigen3 | ublas | blitz++] and HDF5 datasets
http://h5cpp.org
Other
142 stars 32 forks source link

guidance for OpenCV cv::Mat support #60

Open eudoxos opened 4 years ago

eudoxos commented 4 years ago

Hi, I would like to add support for OpenCV matrices (cv::Mat). All supported matrix classes in H5M* are templated based on scalar type (plus other things); cv::Mat, on the other hand, stores its datatype internally. I usually use a simple switch/case function to map OpenCV type constants to HDF5 constants and vice verse.

Could I get some guidance how to hook that into h5cpp? I appreciate very much compactness of the code, esthetically and as programmer, but need a bit of help at first :)

steven-varga commented 4 years ago

Thanks for the interest! Can you tell me the relationship between cv::Mat, cvMat_?

eudoxos commented 4 years ago

cv::Mat_ is a thin static-typed accessor for underlying cv::Mat (which can hold data of any type) for convenience. So e.g. cv::Mat with CV_F32 type (float) can be wrapped in cv::Mat_<float>, giving the compiler static knowledge about interpreting the underlying storage.

The type most the time is definitely cv::Mat, though.

eudoxos commented 4 years ago

To explain more, cv::Mat has publicly-accessible rows and cols data members (for array size), the array is stored always as row-major. Rank of cv::Mat is 2 (when cv::Mat::channels()==1, 1-channel per pixel) or 3 (with more channels).

Raw data can be accessed with the data pointer cv::Mat::ptr(), though cv::Mat does not guarantee being continuous — it can be, and often is, a region inside another, larger, cv::Mat, and only proxies access to the "parent" data. This can be checked with cv::Mat::isContinuous(). If not continuous, deep-copy (with continuous storage) can be obtained with cv::Mat::clone().

Type of data stored is accessed with cv::Mat::depth() (which returns the underlying datatype, CV_8U, CV_16U and so on).

steven-varga commented 4 years ago

Thanks, will take a look at it in a week or so -- I am up for a presentation, then a workshop.

A copy (you call it deep copy) may be prohibitively expensive with a large matrix, or in cases when the matrix is half the size of the available memory -- erroneous. The 'continuous' case is relatively easy to handle. I am interested in learning more about the cases where cv::Mat::isContinuous() returns false. Is this have to do with sub matrices? If I may ask: How are you involved with OpenCV?

eudoxos commented 4 years ago

I am just a regular user of OpenCV. I store most data in Eigen arrays but for some (computer-vision related) algorithms, I map the data to cv::Mat. Dumping those directly to hdf5 would be elegant, but it is mostly a convenience for me.

Non-continuous matrix is a submatrix, yes. Algorithms operate on matrix or sub-matrix (they call it image and region, or region of interest or ROI) without necessarily making the distinction.

The non-continuous case could just fail for now, that would be fair enough. Maybe later some expert (don't think that is me) might write a routine converting ROI information obtained from cv::Mat::locateROI into HDF5 hyperslab specification.

steven-varga commented 4 years ago

An update: thanks for the input! Maybe we could have an online chat on suitable day? I live in Toronto -- time zone wise. Here is the thing, as it appears OpenCV doesn't use templates to indicate the underlying type, which makes it different from other packages. The next version H5CPP type system is reworked/upgraded, and can accommodate OpenCV with ease, but won't be available for another few weeks.

The alternative is to make it happen for the current version, and then forward propagate it to the new internal type system. Either way, for an efficient zero copy solution I need to have a good understanding of use case, and behaviour of OpenCV. And perhaps you could help me with that.

best: steve

eudoxos commented 4 years ago

No problem waiting a few weeks for the next type system. I will contact you for a chat, I am Europe-based but we will find some overlap for sure.