1

I want to do processing on images with C++ and have been using OpenCV. I've gotten a bit stuck though when it comes to trying to access each pixel individually. I can output the whole gray scaled image just fine using:

cout << image;

and get the expected output of values like so:

[143, 147, 164, 177, 177, 185, 196, 195, 185, 186, 178, 190, 178, 163, 183...

But when I try to output one pixel at a time using:

for (int y = 0; y < image.rows; ++y) {
    for (int x = 0;x < image.cols; ++x) {
        std::cout<<image.at<double>(y, x)<<" ";
    }
            cout << endl;}

my output is a bunch of large numbers like these:

-2.98684e+18 -1.21685e-83 -1.91543e-113 -1.8525e-59 -2.73052e-127 -2.08731e-35 -3.72066e-103 ...

Any thoughts as to what I am missing or doing wrong?

  • are you sure that those are doubles? – Marco A. Mar 21 '14 at 21:49
  • 1
    where does `image` come from? what datatype is it? most probably `` is just the wrong datatype to interpret the values. Try `image.at(y,x)` or if it is not grayscale but BGR try `image.at(y,x)`. – Micka Mar 21 '14 at 21:50
  • did you check your image.type() that should be CV_8U=0 or CV_8UC3=16? Reading video sometimes produces mistakes in terms of number of channels. – Vlad Mar 22 '14 at 00:40
  • @Micka I'm getting my image from a video frame and then converting it to grayscale like this: `Mat frame;Mat image;` `VideoCapture vid(".../test_file.mp4");` `vid.read(frame);` `cvtColor( frame, gray_image, CV_BGR2GRAY );` – user3448181 Mar 22 '14 at 00:41
  • @Vlad I also tried using `cout<(y, x)<<" ";` and now my outputs look like this: `\217 \223 \244 \261 \261 \271 \304 \303 \271 \272...` – user3448181 Mar 22 '14 at 00:42
  • @Vlad I ran `cout << image.type();' and it outputs `0`. Does this mean it is CV_8U? – user3448181 Mar 22 '14 at 01:33
  • Yes. You should be fine. – Vlad Mar 22 '14 at 01:54

2 Answers2

1

since your values [143, 147, 164, 177...] look like uchar type your Mat type should be either CV_8U=0 or CV_8UC3=16, which you can check with image.type(). So your output should be (as @Micka noted)

std::cout<<image.at<uchar>(y, x)<<" "; // gray
or
std::cout<<image.at<Vec3b>(y, x)<<" "; // color

In the future just use this in order to stop worrying about the type:

Rect rect(0, 0, 10, 10); // print 10x10 block
cout<<image(rect)<<endl;

Not to say that knowing type isn't important though.

Vlad
  • 4,425
  • 1
  • 30
  • 39
0

If you want to print all pixels of the image, you can simply use:

cout << image << endl;

If you want to print a pixel, use:

cout << image.at<Vec3b>(y, x) << endl; // for color image

or

cout << (int) image.at<uchar>(y, x) << endl; // for gray-scale image

Note that, in the last line, casting it to int is needed. For details, check out Why "cout" works weird for "unsigned char"?.

Community
  • 1
  • 1
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174