0

I've c++ and OpenCV 3.1 and i separated the RGB three channels with these code :

Mat src = imread("original_image.jpg",CV_LOAD_IMAGE_COLOR);
Mat bgr[3] , bluemat ;
split(src,bgr);
bluemat = bgr[0];
std::cout << "bluemat.at<int>(0,1); : " << bluemat.at<int>(0,1) << '\n';

The strange thing is it print out a big number : 1415208581 , why is that ?

Isn't it suppose to be in 0-255 range ? why it is not ?

komoboji
  • 11
  • 1

2 Answers2

1

(expanding comment for search)

A feature of openCV is that the cv::Mat image type is a very simple object based on the original C version of the library.

The cv::Mat contains a field giving the pixel type but the data is stored simply as a block of memory bytes. You can use this block of memory to store and access pixels however you want. It makes it very flexible and easy to link with other libraries, but means you need to manually keep track of what the data is.

So data.at<int>(0,0) will extract the first pixel as if the data was ints (whatever int is on your platform), data.at<uchar> (0,0) will get the first pixel as a byte (which is generally what you want).

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • Thank you for your answer, but it (uchar or unsigned char) return a null value, and it print nothing. and if i change it to (0,0) it return one of those mysterious character(like question mark in rectangle). – komoboji Jun 04 '17 at 15:27
  • I found the answer but,casting byte to uchar and then to int ! why ? could you explain it more ? why not directly to int works ? – komoboji Jun 04 '17 at 15:37
  • @komoboji, you are confusing two things. you need the argument to cv::Mat "at" to tell it how big a pixel is in memory, but then you need an int argument to "cout" to tell it to print the result as a number and not as a printable character. So something like cout << (int) << data.at(0,0) – Martin Beckett Jun 04 '17 at 16:00
0

The main difference here is casting the memory byte to uchar vs int. What form the data you have depends on how you read it in. CV_LOAD_IMAGE_COLOR read the image as 16-bit/32-bit values. I cannot compile the code you gave me becuase of the memory issues that are created by converting that data to an int.

Now, if you use uchar, that will be solved. The problem however with the cout printing a character, has to do with the overload functions of <<

Mat src = imread("1.jpg", CV_LOAD_IMAGE_COLOR);

Mat bgr[3], bluemat;
split(src, bgr);
bluemat = bgr[0];
std::cout << "bluemat.at<uchar>(0,1); : " << (int)bluemat.at<uchar>(0, 1) << '\n';

What I changed was just to insert the typecast int. This issue is expanded here, but tells the output stream that this is a number, not a character.

pastaleg
  • 1,782
  • 2
  • 17
  • 23