How to access elements of a std::vector<cv::Mat> and put them in separate matrices cv::Mat

589 Views Asked by At

I have a const std::vector<cv::Mat> containing 3 matrices (3 images), and in order to use each image further in my program I need to save them in separate matrices cv::Mat. I know that I need to iterate over vector elements, since this vector is a list of matrices but somehow I can't manage it. At the end, I also need to push 3 matrices back to a vector. I would appreciate if someone could help me out with this. I am still learning it.

std::vector<cv::Mat> imagesRGB;
cv::Mat imgR, imgG, imgB;

for(size_t i=0; i<imagesRGB.size(); i++)
{
   imagesRGB[i].copyTo(imgR);
}
1

There are 1 best solutions below

0
On BEST ANSWER

In your code, note that imagesRGB is uninitialized, and its size is 0. The for loop is not evaluated. Additionally, the copyTo method copies matrix data into another matrix (like a paste function), it is not used to store a cv::Mat into a std::vector.

Your description is not clear enough, however here's an example of what I think you might be needing. If you want to split an RGB (3 channels) image into three individual mats, you can do it using the cv::split function. If you want to merge 3 individual channels into an RGB mat, you can do that via the cv::merge function. Let's see the example using this test image:

//Read input image:
cv::Mat inputImage = cv::imread( "D://opencvImages//lena512.png" );

//Split the BGR image into its channels:
cv::Mat splitImage[3];
cv::split(inputImage, splitImage);

//show images:
cv::imshow("B", splitImage[0]);
cv::imshow("G", splitImage[1]);
cv::imshow("R", splitImage[2]);

Note that I'm already storing the channels in an array. However, if you want to store the individual mats into a std::vector, you can use the push_back method:

//store the three channels into a vector:
std::vector<cv::Mat> matVector;

for( int i = 0; i < 3; i++ ){
    //get current channel:
    cv::Mat currentChannel = splitImage[i];
    //store into vector
    matVector.push_back(currentChannel);
}

//merge the three channels back into an image:
cv::Mat mergedImage;
cv::merge(matVector, mergedImage);

//show final image:
cv::imshow("Merged Image", mergedImage);
cv::waitKey(0);

This is the result: