a cv::Mat of std::vector … how do I?

2019-07-24 17:21发布

问题:

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.

回答1:

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 ?



回答2:

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


回答3:

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


标签: vector opencv