smttsp
smttsp

Reputation: 4191

How to create a 4D matrix from a vector of matrices in OpenCV c++

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

Answers (1)

smttsp
smttsp

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

Related Questions