# Is there a way to easily plot pixels?

Let's say I have a Mat M which contains a grayscale image. Now I apply a colormap to make a new Mat M_color and show the image. The colormap is fine, but at specific points (where I already know the indices), I want to make the pixels a specific color (let's say black).

Example: I have a 25x25 grayscale image shown with a rainbow colormap. At pixels (2,7), (4,12), (16,9), and (14,23) I want them to be black.

Is there an easy way to plot the black pixels over-top the rainbow image? Or if it's easier, to just change the color at that specific instance to black.

edit retag close merge delete

Sort by » oldest newest most voted

Depending on your application, you could draw circles around the points instead of making the pixels specifically coloured. There are OpenCV functions to do this. But yes, you can change the color at that specific instance to black by doing something like this --> image.at<uchar>(Points(x, y)) = 0;

Edit: Here is the function for drawing a circle around a point circle(image, co-ordinates, radius, color) --> Where image is the source image, co-ordinates are the points where you want the center of the circle to be (Point(x,y)), radius is an integer value with the circle radius, and color is the color of the circle. (Scalar(0, 0, 0) for a black circle).

Additionally, you could also create a rectangle with your four points as the edges.

more

Thanks for the help. Since I want multiple circles, I have to apply the circle function multiple times? Also, doesn't this exceed the size of one pixel? What I mean by this is let's say the circle radius is one, this will technically circle around more than one pixel because the pixel value is just the center, correct?

Other question, let's say I use image.at<uchar>(Point(x, y)) = 0; does uchar work for CV_8U datatype? Sorry, I know that question is really basic. And finally, let's say I want to make the color turquoise instead of black. Do I say: image.at<uchar>(Point(x, y)) = Scalar(R,G,B); where R,G,B are the proper values for whatever color I want?

( 2015-03-10 16:54:39 -0500 )edit
2

just as a sidenote, if that operation is after applying a colorMap, it should be: image.at<Vec3b>(y,x) = Scalar(b,g,r);

( 2015-03-10 16:55:59 -0500 )edit

Thanks berak. This might be a dumb question, but why is it (y, x) instead of (x, y)? Is that just the convention when you do <Vec3b>? Or is it because you are using image.at?

EDIT: Nevermind, I looked at the documentation.

( 2015-03-10 17:02:53 -0500 )edit

Point goes x,y - while cv::Mat is at<type>(row,col); so either:

img.at<type>(y,x); or img.at<type>(Point(x,y));

( 2015-03-10 17:17:26 -0500 )edit

Yes @TrustMeImAnEngineer, you would need to draw the circle function 4 times. 1 for each point. And @berak was right, since the color map has been applied, you would need to use image.at<Vec3b>(y,x) = Scalar(b,g,r); where b g r are the proper values for the colour turquoise.

( 2015-03-11 09:16:22 -0500 )edit
1

In a sense it is a convention, but a historical one. Data storage on a computer is always 1D, so if you look at C-code and you have anarray[y][x], where 'x' is the inner array and 'y' is the outer one. So the convention is to scan in rows like an old TV will do.

There now a huge speed difference between

for(int y=0; y < Ymax; y++) {
for(int x=0; x < Xmax; x++) {
int something = array[y][x];
}
}


and

for(int y=0; y < Ymax; y++) {
for(int x=0; x < Xmax; x++) {
int something = array[x][y];
}
}


where the first example reads the data continous and the second one does not

( 2015-03-11 15:12:56 -0500 )edit

Official site

GitHub

Wiki

Documentation