1

I'm trying to create an openCV matrix where each element of the matrix is a std::vector... but I can't seem to get it to work. Here's what I'm doing:

cv::Mat_<std::vector<double> > costVol(3,5);
std::vector<double> slice0;
slice0.push_back(8.0);
costVol(0,1)=slice0;

The entire code compiles but at costVol(0,1)=slice0; it throws a memory access error. I'm guessing this is because the matrix has not been initialized properly... can somebody tell me how to initialize the cv::Mat costVol properly. I'd ideally like it to be initialized to an empty vector or even a vector of size lets say 5 with all elements 0 by default.

Mustafa
  • 367
  • 1
  • 4
  • 13
  • wow.. i've never had a question with no responses for 2 hours! Is this a really dumb question? I tried to use `cv::Mat_ >` and it worked but that openCV requires that numChannels be known at compile time. That beats the purpose of using std::vector. numChannels is only known to me at run time. – Mustafa Oct 13 '11 at 22:59
  • how did you finally solve this? – ssb Jan 17 '13 at 12:12

3 Answers3

2

I'm not sure that you can do this in this way - AND I'm pretty sure you don't want to!

cv::Mat is intended to store a 1 or 2 dimensional array of a few predefined built in types for image processing. You can have it use your own external storage (which can be in a vector) for the actual data and use it's mapping functions - but you can only do this for types that match it's range of predefined built-ins.

eg.

std::vector<double> myData;

// fill with 100 items
myData.push_back(.....);

// create a 10x10 cv::Mat pointing at the 100 elements of myData
cv::Mat matrix(10,10,CV_32FC1,&myData.front()); 

What are you trying to do ?

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • hmm... that is very close to what I want to do. I want to basically build a 3D volume. The cv::Mat indexes a height x width area in space while the vector indexes a discretized depth in space. I want it to be a vector because only some depths have a value associated with them. The code you've outlined above... is every (i,j) element of the matrix pointing to the same myData ? Can each (i,j) point to different myData... that is unique to each (x,y) position in space I want to maintain a unique vector of values on certain depths at (x,y) – Mustafa Oct 14 '11 at 00:05
  • 1
    cv::Mat can store N-dimensions. – mevatron Oct 14 '11 at 01:49
  • @Mustafa - you could store a cv::Mat of pointers to vectors (assuming your machine has a pointer size that would fit in one of the CV_xxC1 types) but there are better ways of doing a 3D vector in openCV – Martin Beckett Oct 14 '11 at 04:11
  • I see.. I ended up using a vector > >... bah.. not very satisfying... but I'm going to tackle any later issues as they come up... – Mustafa Oct 14 '11 at 16:26
1

If all your vectors have the same small fixed length, then the best choice will be a multichannel Mat (supported number of channels is 1-512):

typedef cv::Vec<double, 5> Vec5d;

cv::Mat costVol(3, 5, Vec5d::type);
costVol = Vec5d::all(0.0);//set all elements of costVal to zero

//find minimum at (i,j) location
double min;
cv::minMaxLoc(costVol.at<Vec5d>(i,j), &min);
Andrey Kamaev
  • 29,582
  • 6
  • 94
  • 88
0

Why not use a 3D matrix?

The Mat class can be turned into a cube via usage like this:

// create a 100x100x100 32-bit array
int sz[] = {100, 100, 100};
Mat bigCube(3, sz, CV_32F, Scalar::all(0));

Or, if you need the space saving qualities of a "jagged" 3D matrix, you could look at the SparseMat class.

Also, if you're doing this at run-time, you could do something like:

int sz[3]
int dimSize[3];

// fill in your dynamic dimensions here...

for(int i = 0; i < 3; i++)
{
    sz[i] = dimSize[i];
}

Mat* threeD = new Mat(3, sz, CV_32F, Scalar::all(0));
mevatron
  • 13,911
  • 4
  • 55
  • 72
  • The problem with using the Mat class as a 3D array is that there isn't any existing functionality to find the minimum along a certain dimension. If you imagine the matrix as a plane and the 3rd dimension as depth, then I want to be able to take minimums along the depth direction at each (x,y) location. openCV doesn't have any pre-existing functionality for this. – Mustafa Oct 14 '11 at 16:24