Drawing Grid Lines On Images Using Python

This is a full tutorial on drawing grid lines on images using python. We will be using matplotlib and PIL libraries to accomplish this task.

First, let us understand what matplotlib and PIL are. This will help us understand how to create gridlines on a given image using these libraries.

 

Draw Grid Lines on Image Using Matplotlib in Python

In this tutorial, we are drawing grid lines on an image using matplotlib and PIL.

Placing grid lines on images can serve several purposes. It is primarily done to create clusters for image processing based on a segmentation algorithm. Therefore, unnecessary grids can be removed. After comparison with the target-dataset, we can reduce the amount of data being fit into a dataset.

 

Let us go through the code snippets and learn line by line on how to add gridlines to an image:

Imports:
import matplotlib.pyplot as plt
import matplotlib.ticker as plticker
try:
    from PIL import Image
except ImportError:
    import Image

First, we need to import matplotlib.pyplot library referring to it as plt. The pyplot library holds in it the reference to the grid() method. We will be using this later to plot the grid lines on the image.

Next, we need to import matplotlib. Ticker library and referring to it as plticker. The user can set the grid intervals for the image using the Ticker module.

After importing all the required libraries from matplotlib we import the Image module from PIL library. The Image module will help us import the image into the code and manipulate it if necessary. Also, the modified image is saved using this module. We use the try() and except() blocks while importing this module as it is prone to Import Errors.

 

Opening the image: 

Once we have imported all the necessary modules and libraries, we can start the actual coding for drawing the grid lines.

image = Image.open('Image.png')

 

The above line opes the target image present on the local machine. Furthermore, the image must be a .png file. Because the PIL library does not support the JPEG file format for images. Please note that the image and the code should be in the same directory. If you want to open an image that is present in a different directory, the absolute path of the image file must be provided.

 

The below code snippet demonstrates the method of opening the image that is located in another directory.

image = Image.open('E:\\Image Folder\\Image.png')

Note: Use the path that the Image is present in your local system(The above path is just an example).

 

Preparing the image to draw grid lines:

Once we have opened the image in the code we can set it up to add our grid lines:

gridLineWidth=100
fig=plt.figure(figsize=(float(image.size[0])/gridLineWidth,float(image.size[1])/gridLineWidth), dpi=gridLineWidth)
axes=fig.add_subplot(111)

In the above code snippet, we use the variable gridLineWidth to initialize the size of the grid lines. So, increasing this value increases the width of the grid lines.

In the next line, we take the size of the image by using the figure() method. Here image.size[0] indicates the width of the image. Similarly, image.size[1] indicates the height of the image. We divide the width and height of the image by the gridLineWidth to determine the number of grid squares that can be created. Further, we pass the dpi(dots per inches) parameter. It determines how many pixels the figure comprises and equates it to our gridLineWidth.

The add_subplot() method acts as a container for all plot elements. For instance, it holds information about the axes and the number of grid boxes that can be created for a target image.

 

fig.subplots_adjust(left=0,right=1,bottom=0,top=1)

The above line removes white spaces present around the image. Skipping this line will not affect the rest of the code.

 

Marking the grid lines on the image:

Next, we can set up the grid intervals. Grid intervals are the size of the grid squares that appear on the image.

gridInterval=100.
location = plticker.MultipleLocator(base=gridInterval)
axes.xaxis.set_major_locator(location)
axes.yaxis.set_major_locator(location)

In the above code snippet, we configure the grid spaces and where the grids should appear on the image. Here we set the variable gridInterval’s value to 100. So, increasing this value increases the size of the grid squares.

Next, we use the plticker library and call the MultipleLocator method to set the number of ticks(grid lines) in both axes. We are using the set_major_locator() method to set the ticks for each axis. The method takes the location of the ticks as input.

 

Drawing grid lines on the image:

After locating where the gridlines have to be drawn, we can go ahead and draw the grid lines onto the image. The below code snippet adds gridlines onto the target image.

axes.grid(which='major', axis='both', linestyle='-', color='k')
axes.imshow(image)

The grid lines are drawn onto the image using the grid() method. The grid() method takes several parameters:

  • which – It refers to the grid lines to apply the changes on(Here we are using major).
  • axis – It refers to the axis in which the grid lines have to be drawn(Here we pass the value as ‘both’ as we need grid lines on both axes.We can pass  ‘x’ or ‘y’  instead of both if the grid lines are required only that respective axis).
  • linestyle – It refers to the style of line that the grids appear in. ‘-.’ Can be passed as the value to get dotted lines instead of solid lines.
  • color –  The color parameter is optional and when not passed it defaults to white.

Next, we use the imshow() method to add the image to the local variable within the code. It saves the image within the code with all the changes applied(This does not save the image to the file system).

 

Adding labels to the grid squares:

Next, we can add labels to the grids(display grid numbers inside the grid space).

nx=abs(int(float(axes.get_xlim()[1]-axes.get_xlim()[0])/float(gridInterval)))
ny=abs(int(float(axes.get_ylim()[1]-axes.get_ylim()[0])/float(gridInterval)))

for j in range(ny):
y=gridInterval/2+j*gridInterval
for i in range(nx):
x=gridInterval/2.+float(i)*gridInterval
axes.text(x,y,'{:d}'.format(i+j*nx), color='k', fontsize='25',  ha='center', va='center')

(Note: We can omit the above code snippet. The grids will still appear on the image without the above code snippet. So, if you do not require the numbers to be displayed inside, the grid spaces please skip the above lines of code.)

 

Next, we calculate the number of grid squares in x and y axes. Consequently, we store them into nx and ny variables respectively. Two nested for loops have been used to iterate through the grids. We use axes.text() method to write the numbers into the grid spaces. We pass the x and y axes as the required axes and also the font color as well as the font size.

Here ha is the alignment of the text in the horizontal axis. Similarly, va is the alignment of the text in the vertical axis.

 

Saving the image onto the file-system:

The final step is to save the image into our local file system.

fig.savefig('myImageGrid.png',dpi=gridLineWidth)

The above code snippet saves the image into the local filesystem. The user assigns the name of the image. Save the image with .png extension. It automatically saves the image in the same directory the code is saved by default. If you want to save the image in a different directory then mention the absolute path of that directory.

 

The below code snippet demonstrates how to store the image in a user-defined directory.

fig.savefig('E:\\Image Folder\\myImageGrid.png', dpi=gridLineWidth)

 

The complete code for drawing grid lines on an image is as follows:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker
try:
    from PIL import Image
except ImportError:
    import Image

# Open image file
image = Image.open('Image.png')

# Set up figure
gridLineWidth=100
fig=plt.figure(figsize=(float(image.size[0])/gridLineWidth, float(image.size[1])/gridLineWidth), dpi=gridLineWidth)
axes=fig.add_subplot(111)

# Remove whitespace from around the image
fig.subplots_adjust(left=0,right=1,bottom=0,top=1)

# Set the gridding interval: here we use the major tick interval
gridInterval=100.
location = plticker.MultipleLocator(base=gridInterval)
axes.xaxis.set_major_locator(location)
axes.yaxis.set_major_locator(location)




# Add the grid
axes.grid(which='major', axis='both', linestyle='-', color='k')

# Add the image
axes.imshow(image)

##The below lines can be skipped if labelling of grids is not required
# Find number of gridsquares in x and y direction
nx=abs(int(float(axes.get_xlim()[1]-axes.get_xlim()[0])/float(gridInterval)))
ny=abs(int(float(axes.get_ylim()[1]-axes.get_ylim()[0])/float(gridInterval)))

# Add some labels to the gridsquares
for j in range(ny):
    y=gridInterval/2+j*gridInterval
    for i in range(nx):
        x=gridInterval/2.+float(i)*gridInterval
        axes.text(x,y,'{:d}'.format(i+j*nx), color='k', fontsize='25',  ha='center', va='center')
##Can be skipped until here


# Save the figure
fig.savefig(‘myImageGrid.png', dpi=gridLineWidth)

Leave a Reply

Your email address will not be published.