« Image Zoom and Pan...

Pixel Grid Update

Steve Eddins
Posted on Wednesday, October 30, 2024

Today’s post describes recent updates to Pixel Grid, one of my File Exchange submissions. I have previously written about Pixel Grid in my 17-Feb-2011 and 13-Jun-2019 MATLAB Central blog posts.

Pixel Grid is meant to subtly outline the pixel edges when an image is displayed so that the pixels are very big on the screen. Here is an example.

bw = [...
    0 0 0 1 0 0 0
    0 0 1 0 1 0 0
    0 1 0 0 0 1 0
    1 1 1 1 1 1 1 ];

imshow(bw, 'InitialMagnification', 'fit')

figure_0.png

(How many rows are in the image displayed above?)

pixelgrid

figure_1.png

Before I describe the updates, I’d like to recap the key implementation techniques involved.

Drawing Many Line Segments Efficiently

If an image has thousands of rows and columns, then drawing a complete pixel grid requires thousands of line segments. The MATLAB graphics system can draw all those line segments much faster if we can somehow minimize the creation of graphics line objects. As it turns out, there are several ways to draw all the line segments with just one line object. My preferred method is to draw N + 1 vertical line segments and M + 1 horizontal line segments (for an MxN image matrix), with the segment vertices separated by NaN values in the XData and YData properties.

To illustrate the technique, consider an image with 10 rows and 15 columns. Here is one way to draw the entire grid with a single line object. First, construct vectors of x and y vertices for the vertical line segments, with the segments separated by NaN values.

M = 5;
N = 10;
xv = (0:N) + 0.5;
xv = [xv ; xv ; NaN(1,N+1)];
xv = xv(:);

yv = [0.5 ; M+0.5 ; NaN];
yv = repmat(yv,1,N+1);
yv = yv(:);

Drawing what we have so far:

plot(xv,yv)
axis equal
axis ij
axis padded

figure_2.png

Now construct arrays containing vertices for the horizontal line segments.

xh = [0.5 ; N+0.5 ; NaN];
xh = repmat(xh,1,M+1);
xh = xh(:);

yh = (0:M) + 0.5;
yh = [yh ; yh ; NaN(1,M+1)];
yh = yh(:);

Here’s what the horizontal line segments look like:

plot(xh,yh)
axis equal
axis ij
axis padded

figure_3.png

The horizontal and vertical line segment vectors can be combined and then drawn together:

x = [xh ; xv];
y = [yh ; yv];
plot(x,y)
axis equal
axis ij
axis padded

figure_4.png

Guaranteeing Grid Visibility

Consider again the first image shown above:

imshow(bw, 'InitialMagnification', 'fit')

figure_5.png

How can we draw pixel grid lines so they will always be visible, no matter what the image pixel color is underneath?

Fundamentally, the answer is to draw the line using two contrasting colors. With MATLAB graphics, two techniques come to mind:

Here is the first technique:

plot(x,y, Color = "black", LineWidth = 3)
hold on
plot(x,y, Color = "white", LineWidth = 1)
hold off
axis equal
axis ij
axis padded

figure_6.png

And here is the second:

plot(x,y, Color = "black", LineWidth = 1, LineStyle = "-")
hold on
plot(x,y, Color = "white", LineWidth = 1, LineStyle = "--")
hold off
axis equal
axis ij
axis padded

figure_7.png

For Pixel Grid, I wanted to keep the grid visible but subtle, so I have used the second technique with thin lines and different shades of gray.

imshow(bw, 'InitialMagnification', 'fit')
pixelgrid

figure_8.png

Pixel Grid Update: Automatic Visibility Control

It only makes sense to create and display a pixel grid of the image pixels are very large on the screen. At a typical magnification level, a visible pixel grid would completely obscure the image. Previous versions of Pixel Grid left it to the user to know when it makes sense for the pixel grid to be created and to be visible.

With the latest Pixel Grid update, you can add it to any image, and the grid will automatically stay invisible until you zoom in far enough to make the individual pixels big.

A = imread("roses.jpg");
imshow(A)
pixelgrid

figure_9.png

In the image displayed above, the pixel grid has been added but is not visible. If you zoom in far enough, the grid becomes visible automatically:

zoomImage(100)

figure_10.png

And when you zoom back out a bit, the pixel grid automatically becomes invisible again.

zoomImage(0.5)

figure_11.png

The automatic visibility control is implemented using the MarkedClean event, as described on Yair Altman’s 27-May-2015 blog post, “Undocumented HG2 graphics events”.

Automatic visibility control also uses my recent File Exchange submission, “Image Zoom Level and Pan Utilities”, to determine the approximate physical size of image pixels on the display. This submission also contains the zoomImage function used above.

Wrap-Up

Pixel Grid has been around for a while on the File Exchange, but there is a recent update on the File Exchange that makes it more convenient to use.

If you use Pixel Grid in your own work with MATLAB, I’d be interested to know your thoughts about it. To send me questions or comments about this post, or about other posts, choose “Contact” from the navigation menu.