extract RGB values from ptr[c] = cv::Vec3b(ptr[c][2], ptr[c][1], ptr[c][0]);

asked 2020-04-06 14:32:47 -0500

andrei186 gravatar image

I have been trying to modify pixels value using pointers with the code borroweded from https://riptutorial.com/opencv/exampl...:

  for(int r = 0; r < image.rows; r++) {
    // We obtain a pointer to the beginning of row r
    cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);

    for(int c = 0; c < image.cols; c++) {
        // We invert the blue and red values of the pixel
        ptr[c] = cv::Vec3b(ptr[c][2]=0, ptr[c][1], ptr[c][0]=0);

this works fine and as expected shows the picture as shades of green . Yet I cannot access B, G or R individually to perform a threshold algorithm.

cout <<  "*ptr = "<< *ptr<< std::endl;

returns an array of BGR values *ptr = [0, 65, 0]

What would be the syntax to extract B, G and R from this array individually?

edit retag flag offensive close merge delete


idon't understand your problem. you already have ptr[c][0] ?

berak gravatar imageberak ( 2020-04-07 00:47:28 -0500 )edit

that is what I did, but

cout <<  "ptr[c][0]="<< ptr[c][0]<< std::endl;

returns nothing:


tried *(ptr+1), *ptr[1], *ptr[c][0] - return either emptyness or error

andrei186 gravatar imageandrei186 ( 2020-04-07 03:34:46 -0500 )edit

perform a threshold algorithm.

what is it about ? what are you trying to achieve ?

(in most cases, rolling your own "per pixel" loops is a bad idea anyway)

berak gravatar imageberak ( 2020-04-07 04:16:07 -0500 )edit

returns nothing:

try cout << int(ptr[c][0]) << endl;

else it tries to print ascii garbage (uchar data)

berak gravatar imageberak ( 2020-04-07 04:17:36 -0500 )edit

int(ptr[c][0]) worked. Why ptr[c][0] returns nothing, but int(ptr[c][0]) returns an array element?

andrei186 gravatar imageandrei186 ( 2020-04-07 04:44:25 -0500 )edit

"what is it about ? what are you trying to achieve ? rolling your own "per pixel" loops is a bad idea"

Thank you for asking this question for I myself am not sure if I am doing it the proper way.

I am re-inventing a wheel which has been invented and reinvented many times: to control mouse cursor with a laser pointer on a projection screen which is capured by the camera as a trapezoid.

To this end I need first to locate the brightest pixel (or centroid of group of pixels) - i.e. performing thresholding - do you mean that there is more efficient way that "per pixel" loops?

Then I need to remap the coordinates of this centroid from trapezoid to rectangle of a computer screen format (3x4 or 9x16). This is the reason for my another "multiplying homography and image matrix" query

andrei186 gravatar imageandrei186 ( 2020-04-07 05:08:12 -0500 )edit

some ideas:

  • if you have a red laser, extract the red channel (extractChannel())
  • use minMaxLoc() on that (you get the brightest value and pos)
berak gravatar imageberak ( 2020-04-07 07:00:20 -0500 )edit

Problem is that there are other bright spots on the screen, especially if the direct sunlight is present and in a school class rooms this is always the case as the windows usually look southward (I am doing this for school and the system we purchased for the purpose goes unstable when sunlight is present so we have to use blindes). I experimented a lot with cameras and different red filters (with the glass ones, not with the mathematical!) and it looks that though the laser is red (635-650nm) the most reliable laser dot identification happens with the sum R+G+B (which is actually gray scale) rather than with just red channel, which came as a surprise to me.

minMaxLoc() seems to be exactly what is needed. I will experiment with it, thank you for the hint.

andrei186 gravatar imageandrei186 ( 2020-04-07 08:17:49 -0500 )edit

minMaxLoc() unfortunately only works on single channel images,like grayscale or red only

berak gravatar imageberak ( 2020-04-07 08:38:01 -0500 )edit

Pity but thank you for warning. I can turn it into gray but it will be an extra loop, where as the brightest centroid's coordinates could be found with just single passage through the array.

Just one more question which I anticipate at the next step. When the centroid's coordinates in the perspective-corrected image are calculated, how shall I generate a mouse-click or mouse-move at these coordinates and pass it to another application?

andrei186 gravatar imageandrei186 ( 2020-04-07 08:51:53 -0500 )edit