Ask Your Question

# Make a 3D mat from a std::vector of 2D mat

Hi,

I have a std vector of several 2D Mat std::vector<cv::Mat> matList, and instead of accessing the pixel values in the third dimension by using, e.g., matList.at(k).at<float>(i, j), i'd like to have a 3D mat so that I would access that same pixel using mat3D.at<float>(i, j, k). k can be up to several hundreds. What would be the most efficient way to make this conversion, apart from assigning each pixel explicitly?

edit retag close merge delete

## Comments

You can create that class

( 2016-01-11 07:14:36 -0500 )edit

## 1 answer

Sort by ยป oldest newest most voted

I think something like this could work. You should check carrefully this answer...

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
int planSize[] = { 50,100,200 };
Mat voxel(3,planSize,CV_8UC1);

cout << "Size 0 = " << voxel.size[0] << "\n";
cout << "Size 1 = " << voxel.size[1] << "\n";
cout << "Size 2 = " << voxel.size[2] << "\n";
for (int i = 0; i<voxel.size[0]; i ++)
for (int j = 0; j<voxel.size[1]; j ++)
for (int k = 0; k<voxel.size[2]; k ++)
voxel.at<uchar>(i,j,k)=saturate_cast<uchar>(abs(i-voxel.size[0]/2)+abs(j-voxel.size[1]/2)+abs(k-voxel.size[2]/2));

bool fin=false;
int indPlan=0;
Range rangesVoxel[] = { Range(0,voxel.size[0]), Range(0,voxel.size[1]),Range(0,voxel.size[2]) };
for (;!fin;)
{
rangesVoxel[0] = cv::Range(indPlan,indPlan + 1);
Mat sliceTmp;
sliceTmp= voxel(rangesVoxel).clone();
sliceTmp.copySize(finalSlice);
putText(sliceTmp, format("Plane %d", indPlan),Point(10, 10), FONT_HERSHEY_SIMPLEX,1,Scalar(255));
imshow("Plane Histo", sliceTmp);
cout << mean(sliceTmp) << "\n";
char c=waitKey();
switch (c) {
case 27:
fin=true;
break;
case '+':
indPlan = (indPlan++) % (voxel.size[0]-1);
break;
case '-':
indPlan = (indPlan--) % (voxel.size[0]-1);
break;
}
}

}

more

## Comments

Does it work like this Mat voxel(3,planSize,CV_8UC1);, where planSize is int[3]? In fact it is a pointer...

( 2016-01-11 07:28:07 -0500 )edit

May be planSize is not good word. Its mean you have got three dimensions : 50 x 100 x 200. Again I haven't check is everything is good in this answer

( 2016-01-11 07:33:31 -0500 )edit

Thank you for this first proposition. I will have a look and will report back.

( 2016-01-11 10:21:51 -0500 )edit

I don't understand this: voxel.at<uchar>(i,j,k)=saturate_cast<uchar>(abs(i-voxel.size[0]/2)+abs(j-voxel.size[1]/2)+abs(k-voxel.size[2]/2)); Since we are already looping over all the pixels, then at that stage one can as well assign the value of matList.at(k).at(i,j) to the voxel. So, I don't understand how your proposition address this in a faster way.

( 2016-01-12 02:10:02 -0500 )edit

It's only an example. After you can access or modify plane data using this post but it's only a plane. I don't think there is a cube ROI in openCV.

As I wrote in my post I think something is wrong in this program at line

Mat sliceTmp;
sliceTmp= voxel(rangesVoxel).clone();
sliceTmp.copySize(finalSlice);


date return are not good and i don't understand why.This need further investigation...

( 2016-01-13 02:26:24 -0500 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2016-01-11 05:16:36 -0500

Seen: 4,263 times

Last updated: Jan 11 '16