3

What I'm trying to do

I'm trying to paste a subsection of one image onto another for part of a project I'm working on. When I tried to view what I had so far, I saw that calling imshow() on both images to check doesn't actually show that both of them have the same BRG values at the points that they should.

What's wrong

The values are almost always wrong and often half of the screen will show up as black.

IE: pixel [0,1] of firstIMG will have [91,21,30] while secondIMG will have some other values when hovering over the pixel in the imshow() screen

The code

// Randomly create an image of 10x10 pixels
Mat firstIMG = Mat(10, 10, CV_8UC3);
randu(firstIMG, Scalar::all(0), Scalar::all(255));
imshow("First", firstIMG);
waitKey();

// Create a second image of same type as the first
Mat secondIMG = Mat::zeros(firstIMG.rows-5, firstIMG.cols-5, firstIMG.type());

// Iterate through all rows of secondIMG
for(int i = 0; i < secondIMG.rows; i++) {

    // Iterate through all columns of secondIMG
    for(int j = 0; j < secondIMG.cols; j++) {
        secondIMG.at<unsigned char>(i, j) = firstIMG.at<unsigned char>(i, j);
    }   
}

imshow("Second", secondIMG);
waitKey();


What I've tried so far

It will print out the same exact data for both images if I iterate over every pixel of each image, but when I use imshow() on the secondIMG many if not all of the pixels are incorrect.

Despite that, I've also tried accessing and changing the BRG values for the secondIMG in different ways, [like in this post][1]. That still leads to the same result of completely different values at the points that they share.

Finally, I've also tried just straight up clone() the firstIMG with the same size and everything, also leading to the same error as above.

  [1]: https://stackoverflow.com/questions/7899108/opencv-get-pixel-channel-value-from-mat-image
Dan Mašek
  • 17,852
  • 6
  • 57
  • 85
Saemas
  • 81
  • 4
  • 2
    It should be `cv::Vec3b`, not `uchar`. You are using 3-channel image. – Burak May 29 '20 at 20:25
  • You're 100% correct, thanks! – Saemas May 29 '20 at 20:30
  • Maybe you should answer the question in the answer section. This way it would be easier for people to search for the correct answer. – M. Martin May 30 '20 at 07:09
  • Your answer shouldnt be on the question, answer it in below section. – Yunus Temurlenk May 30 '20 at 07:42
  • @Saemas The sections in your question are pretty well. You got my upvote for that. But you do not need solution part in your question. Answers should be neither in questions nor in comments. – Burak May 30 '20 at 09:59
  • 1
    The proper solution would be to take a ROI using `operator()` and then either `clone()`, or use `copyTo()`. In vast majority of cases using OpenCV, explicitly iterating over the individual pixels is unnecessary... especially when it's something this trivial. – Dan Mašek May 30 '20 at 13:13

1 Answers1

1

It should be cv::Vec3b instead of uchar for a color image.

Instead of looping over pixels, you can use optimised built-in functions.

cv::Mat secondIMG(firstIMG.rows, firstIMG.cols, firstIMG.type());
cv::Rect rect(0, 0, secondIMG.cols, secondIMG.rows);  // x, y, width, height

firstIMG(rect).copyTo(secondIMG);
// or
cv::Mat thirdIMG = firstIMG(rect).clone();
Burak
  • 2,251
  • 1
  • 16
  • 33