4

I've looked at different questions already here on StackOverflow, but none seems to helps. What I want to do is quite simple: I have a cv::Point and I need to get the RGB value for the pixel at that point in a cv::Mat so that I can compare it with a stored RGB value.

Now this should be very easy but I've tried 1001 different ways and it just doesnt work for me.

Someone please help me out of my misery!!

edit: both answers below work! I'm kinda new with C++ and didn't know that outputting a unsigned char through cout gives a questionmark! printf offcourse gives the right value!!

Yamaneko
  • 3,433
  • 2
  • 38
  • 57
user458753
  • 147
  • 2
  • 3
  • 15

2 Answers2

9

That's really easy. However the documentation of OpenCV is good at hiding the simple answers.

Here is example code:

cv::Mat3b image = imread(filename);
cv::Point point(23, 42);
cv::Vec3b template;
template[0] = 128; template[1] = 12; template[2] = 64;

const cv::Vec3b& bgr = image(point);
if (bgr[0] == template[0] && bgr[1] == template[1] && bgr[2] == template[2])
   std::cout << "Colors match!" << std::endl;

There are probable better ways of dealing with the cv::Vec, but I forgot. See also the OpenCV Cheat Sheet.

ypnos
  • 50,202
  • 14
  • 95
  • 141
  • thanks for the answer will try it tomorrow, but what is the difference between a cv::Mat and cv::Mat3b? – user458753 Jan 21 '11 at 14:22
  • i have a cv::Mat named oldImage not cv::Mat3b so i first copy it to a cv::Mat3b: cv::Mat3b image = oldImage; then i do as you in your example but when i try outputting it: std::cout << bgr[0] << std::endl; i get a questionmark.. – user458753 Jan 22 '11 at 16:38
  • thanks it worked but im still wondering what the difference is between a cv::Mat and cv::Mat3b.. – user458753 Jan 22 '11 at 20:48
  • Mat3b is a typedef for Mat_ >. Basically it is a Mat with templated type. It is easier/more elegant to access the elements when you know the type at compile time. Mat is a superclass of all Mat_* classes, that's why you can use every cv function also on a Mat_<*>. – ypnos Jan 24 '11 at 09:42
0

It depends on the type of the image/Mat. If the image is just a normal 1 byte for each rgb per pixel, then this is one way to access it. It's pretty efficient, but not the safest way:

// The RGB values are stored in reverse order (i don't know why)
struct RGB { unsigned char b, g, r; };

// Assumes 1 byte for r,g,b
RGB& GetRGB(cv::Mat &mat, cv::Point p)
{
  assert((mat.step/mat.cols) == sizeof(RGB));
  RGB *data = (RGB*)mat.data;
  data += p.y * mat.cols + p.x;
  return *data;
}

If the Mat is of different type, then you will just need to change the structure of RGB to match what you need.

Try changing the type of the image you read in to a normal RGB image with this code:

Mat in, out;
cvtColor(in, out, CV_8UC3);
Nick Banks
  • 4,298
  • 5
  • 39
  • 65
  • well OpenCV and images are both kinda new to me so i dont really know what kinda image it is (sounds stupid i know) but its a png screenshot made on a mac.. – user458753 Jan 21 '11 at 14:24
  • It is probably just an rgb image then. Try the code above, does it work for you? – Nick Banks Jan 21 '11 at 16:56
  • i tried ouputting the result but it seems to be empty.. (RGB pix = GetRGB(mat, point); std::cout << pix.r << pix.g << pix.b << std::endl;) – user458753 Jan 22 '11 at 16:29
  • @user458753 Can I see the code that you use to load in the image? Do you know if the image has alpha values? – Nick Banks Jan 22 '11 at 18:25
  • I added a line of code that checks to see if the sizes are the same, can you see what that gives you. If you don't want to use an assert, just use an if statement and break point. – Nick Banks Jan 22 '11 at 18:50
  • the assertion failed so i guess its a different Mat, how can i find out what kind of Mat it is? – user458753 Jan 22 '11 at 18:56
  • size = 5, and osx says its an png with RGB color space and NO alpha channel – user458753 Jan 22 '11 at 19:06
  • cvtColor(in, out CV_8UC3) results in: OpenCV Error: The function/feature is not implemented () in reshape, file /source/OpenCV-2.2.0/modules/core/src/matrix.cpp, line 1982 – user458753 Jan 22 '11 at 20:01
  • I don't know you must have some weird file, can you try changing the file to a bitmap and trying to, just for testing purposes? Get right of the cvtColor function for that. – Nick Banks Jan 22 '11 at 20:04
  • i must be doing something pretty stupid.. i striped all non related code and used a all white jpg created with photoshop i get questionmarks as result..(updated question) – user458753 Jan 22 '11 at 20:34
  • echo out mat.cols and mat.rows, what do you get? – Nick Banks Jan 22 '11 at 20:40
  • 1440 900 which is the size of the image – user458753 Jan 22 '11 at 20:44
  • damn that really was STUPID all i needed to do was use printf instead of just cout.. – user458753 Jan 22 '11 at 20:46
  • huh, so does it work now? If so, can you set the question as finished (pick my answer), if not, you want to work on it more in chat? – Nick Banks Jan 22 '11 at 20:47
  • thanks for all the effort i still have some problems with my images but i got it working on a all white image now so i'll figure out the rest! – user458753 Jan 22 '11 at 20:50