Ask Your Question
0

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

asked 2016-01-11 05:16:36 -0600

octopode gravatar image

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 flag offensive close merge delete

Comments

You can create that class

thdrksdfthmn gravatar imagethdrksdfthmn ( 2016-01-11 07:14:36 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-01-11 07:17:58 -0600

LBerger gravatar image

updated 2016-01-11 07:19:07 -0600

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;
        }
    }

}
edit flag offensive delete link more

Comments

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

thdrksdfthmn gravatar imagethdrksdfthmn ( 2016-01-11 07:28:07 -0600 )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

LBerger gravatar imageLBerger ( 2016-01-11 07:33:31 -0600 )edit

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

octopode gravatar imageoctopode ( 2016-01-11 10:21:51 -0600 )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.

octopode gravatar imageoctopode ( 2016-01-12 02:10:02 -0600 )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...

LBerger gravatar imageLBerger ( 2016-01-13 02:26:24 -0600 )edit

Question Tools

1 follower

Stats

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

Seen: 5,180 times

Last updated: Jan 11 '16