Quantcast
Channel: OpenCV Q&A Forum - RSS feed
Viewing all articles
Browse latest Browse all 41027

Changing Mat dimensions inplace

$
0
0
As part of a larger project, I have some code that does something similar to the following: cv::Mat some_function() { // get some ND-array Mat mat1 = get_some_mat(); vector dims(mat1.size.p, mat1.size.p + mat1.dims); // ... shuffle the dimensions stored in "dims" (the total() remains the same) std::swap(dims[0], dims[1]); // only an example... // create new mat header for the same data (no copying) Mat mat2(dims.size(), dims.data(), mat1.type(), mat1.data); // return matrix with the shuffled dimensions mat1 = mat2; // <-- is this part safe?? return mat1; // } Is the last assignment safe, or will it mess up the ref count and leak memory? I know the safer option is to just clone the data as in: // return matrix with the shuffled dimensions return mat2.clone(); but I'm trying to avoid making unnecessary copies of data... I'm open to suggestion if there are better ways to reshape the ND-array in-place ... You can assume the following is true: CV_Assert(mat1.isContinuous() && mat1.dims > 3 && mat1.channels() == 1); N.B: I am working with OpenCV 3.0.0 --- ## EDIT: Another thing I tried is to [directly overwrite](http://docs.opencv.org/modules/core/doc/basic_structures.html#mat) the Mat `size` and `step` with those from the shuffled array: // return matrix with the shuffled dimensions std::copy(mat2.size.p, mat2.size.p + mat2.dims, mat1.size.p); std::copy(mat2.step.p, mat2.step.p + mat2.dims, mat1.step.p); return mat1; But it's not quite right.. Apparently something in the `mat1.flags` field needs to be updated as well! Any help? --- ## EDIT2: I found an [overload](http://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html#a13ccd8740a42616d650ae9495e43eb2d) of the `Mat::reshape` method for ND-arrays, unfortunately it's not yet fully implemented and currently throws a `CV_StsNotImplemented` error! // return matrix with the shuffled dimensions return mat1.reshape(mat2.channels(), mat2.dims, mat2.size.p); See the [source code](https://github.com/Itseez/opencv/blob/3.0.0/modules/core/src/matrix.cpp#L4254) (either 3.0 or the master branch)... --- ## Details Let me explain a bit more about my use case. In my actual code, I'm trying to convert the last dimension of any 1-channel ND-array into channels of a ND-array with one less dimension but multi-channels, without copying the data. (Again we can assume that the array is continuous and the destination number of channels is less than `CV_CN_MAX`). As an example, If I had the following array: cv::Mat get_some_mat() { int dims[] = {2,3,4,5}; // I'm really working with arbitrary number of dimensions Mat matnd(4, dims, CV_64F, Scalar::all(0)); return matnd; } I want to convert it from 2x3x4x5 array with 1-channel into a 2x3x4 array with 5-channels, i.e: int dims[] = {2,3,4}; Mat mat(3, dims, CV_64FC(5), Scalar::all(0)); **And I want to avoid unneeded copies**... The above `Mat::reshape` method would have been great, but it's not implemented at the moment! The regular `Mat::reshape` leaves an undesired singleton dimension at the end: matnd.reshape(5, 0); // returns 2x3x4x1 with 5-channel (note the "1" at the end) Thanks and sorry for the long post :)

Viewing all articles
Browse latest Browse all 41027

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>