user3178680
user3178680

Reputation: 43

How to initialize a 2D vector containing opencv:matrices?

For my current project in c++ I need a 2D vector, which contains opencv:Mat Matrices as elements. I found a similar example, which creates a 2D vector of deques, which works perfectly fine:

vector < vector < deque<int> > > deques_vect2D;
deques_vect2D.resize(vect_col, vector <deque<int> > (vect_row, deque<int> (deque_init_size, deque_init_value)));

However, using this for a 2D vector of matrices does not create independent matrices, changing one matrix results in changing every element in the 2D vector. It seems, that only one matrix exist.

// init 2D vector
vector < vector < Mat > > mat_vect2D;
mat_vect2D.resize(vect_col, vector < Mat > (vect_row, Mat(mat_row, mat_col, CV_32S, Scalar::all(0))));

// change only the first Matrix
mat_vect2D[0][0].at<int>(0, 0) = 1;
mat_vect2D[0][0].at<int>(0, 1) = 2;

for (int r = 0; r < num_of_row; r++)
    for (int c = 0; c < num_of_col; c++) {

        cout << mat_vect2D[c][r] << endl;           
}

// results in... (note how every matrix has changed)
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
(...)

Yes, I do need matrices as elements in the 2D Vector, as those are supposed to be input for another algorithm later on (other data types would imply a lot of casting). So I prefer solutions with Matices as elements, the vector however might be replaced by any other 2D structure.

Upvotes: 3

Views: 2405

Answers (1)

marol
marol

Reputation: 4074

I think the problem is you use a fill constructor:

explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());

Constructs a container with n elements. Each element is a copy of val.

(http://www.cplusplus.com/reference/vector/vector/vector/)

So you initialize each element 2D of the same reference to a Mat() object. In above example it works because you store just ints as a values...

Why you don't just initialize in a quite ordinary way:

vector < vector < Mat > > mat_vect2D;
for(int i = 0;i<vect_row;i++) {
    mat_vec2D.push_back(vector<Mat>());
    for(int j=0;j<vect_col;j++)
        mat_vec2D[i].push_back(Mat(mat_row, mat_col, CV_32S, Scalar::all(0)));
}

This will assign to each element of 2d vector a new instance of Mat()

Upvotes: 2

Related Questions