1

I have a std::vector<cv::Mat> which represents voxels in x,y,z dimensions. Each cv::Mat in the vector is a cross section or slice of the volume.

Unfortunately, OpenCV doesn't offer any wrapper for this data type, so I decided to use a non-supported module from the Eigen library called Tensor. I cannot see any constructor in the documentation that would allow me to efficiently convert from vector<cv::Mat> toEigen::Tensor` without needing to reallocate data.

What is the most efficient way to convert from std::vector<cv::Mat> to Eigen::Tensor?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Max Walczak
  • 433
  • 2
  • 12
  • 1
    [Related](https://stackoverflow.com/questions/33668485/eigen-and-stdvector/33669013) and explains why it won't work without reallocation. – Avi Ginsburg Sep 28 '17 at 08:42
  • 1
    @AviGinsburg the question you linked does have a working solution: given that the OP didn't specify what he means by "convert a vector of a vector so that Eigen can use it" a sparse matrix will do ( you can Map a sparse matrix to a vector of vectors without relocation ). That said, I don't think Eigen supports sparse tensors... – Massimiliano Janes Sep 28 '17 at 09:46
  • you could read about cv::MatAllocator and Eigen::TensorMap; never used them myself, but it looks like you can use the former to allocate each mat data contiguously and the latter to map resulting data to a tensor expression without reallocations... – Massimiliano Janes Sep 28 '17 at 10:04
  • cv::Mat::data is allocated in a contiguous way by default. The problem is that ::data in a vector of cv::Mats is not contiguous because it's spaced with cv::Mat class data. – Max Walczak Sep 28 '17 at 11:14
  • @MaxWalczak no, this has nothing to do with the vector, but with having all Mat's memory stored contiguously in a *single* block in order to be passed to a tensor ... for this reason you need a special MatAllocator ( keep in mind cv::Mat is dynamically allocated, the vector turns out just an array of pointers pairs, or something equivalent) – Massimiliano Janes Sep 28 '17 at 12:35
  • If number of vector items are not variable it 's better for you to use Mat of n-channels. In that case all the elements of channels would be in sequential memory order and makes the life easier for you in converting – AMCoded Sep 28 '17 at 19:45
  • How do I construct n-channel mat? What's the maximum number of channels? I remember there was MatND in OpenCV but it's now obsolete... – Max Walczak Sep 29 '17 at 07:20
  • You can use (e.g.) `cv::Mat3f` for a matrix of `Vec3f`. For arbitrary sizes: `cv::Mat_ >`. Also, OpenCVs `Mat` and `Mat_` do support arbitrary dimensional arrays: http://docs.opencv.org/3.0.0/d3/d63/classcv_1_1Mat.html#a156df5a1326dd5c30b187b0e721a5f57 (a similar constructor for `Mat_` is available) – chtz Sep 29 '17 at 11:51

0 Answers0