Reputation: 4191
Suppose that I collect same size, depth and channel images/matrices into a vector
. So, these images are r*c*d
each and I have m
of them in my vector as follows.
vector<string> imgs; --> there are m image paths in these, all are r*c*d resolution
vector<Mat> vec;
for (auto img: imgs ){
vec.push_back(cv::imread(img, COLOR_BGR)); //or gray. doesn't really matter
}
Now, I want to create a 4D Matrix. For example, in python np.array(vec)
would have given me that (assuming vec
is a list). I would like to the same in OpenCV c++ but I couldn't find a solution for this.
I don't want to create a 4D matrix with Mat m(dims, size, type);
, then iterate through all pixels and copy the value as it is very inefficient. I would like to have a technique that will just consider vec<Mat>
as 4D Mat
so that it is going to be super fast. Note that I can have 100
full-resolution images.
I am using Opencv4.2 and c++ on Mac.
Thanks in advance
Upvotes: 0
Views: 1346
Reputation: 4191
After many hours today, I coincidentally found an answer to my question. I will leave the answer here to have a reference for those who battle with OpenCV's documentation to find the correct answer.
vector<int> dims = {m, r, c}; //dimensions
cv::Mat m (3, &dims[0], imgs[0].type(), &imgs[0]);
This creates the 4D matrix from imgs
vector where the type is one of CV_8UC1
, CV_8UC3
or CV_8UC4
depending on the number of channels. The good thing is it doesn't copy the vector.
Although this is not part of the question, to access a pixel in the 4D matrix, you can do the following:
int x = v1, i = v2, j = v3, c = v4; //v1-4 are some random values within their ranges
cout << (int)m.at<Mat>(x).at<Vec3b>(i,j)[c] << " "
<< (int)imgs[x].at<Vec3b> (i,j)[c] << endl;
Both will print c
-th channel of i,j
-th index of x
-th image.
Upvotes: 2