Adding a Border to the Image using NumPy
By: Sameeruddin Mohammed
Tags: Numpy, Python Programming, Matrix Operations, Image Processing, Image Bordering

In this article, we will learn how to add/draw a border to the image. We use OpenCV to read the image. The rest of the part is handled by NumPy to code from scratch. We rely on it for the matrix operations that can be achieved with so much ease.

There are two aspects in which we can start to think:

If the image is read in grayscale , we can simply keep the default color as black . This is because the length of the shape of the image matrix would be 2. Therefore we cannot add a color border whose color value would be of size 3 and thus it cannot be mapped easily.

, we can simply keep the default color as . This is because the length of the shape of the image matrix would be 2. Therefore we cannot add a color border whose color value would be of size 3 and thus it cannot be mapped easily. If the image is read in RGB, we can have a choice to pick the color for the border. This is because the length of the shape of the image matrix would be 3. Hence we can add a color border whose color value would be of size 3 which can be mapped easily.

Before proceeding further, we need to make sure we have enough colors (based on the user’s choice). I have extracted the possible color values from this website.

The code of the same can be seen below. The result is stored in a JSON file named color_names_data.json.

It is necessary to grab R, G, and B values in order for the mapping after the separation of pixels. We follow split and merge methods using NumPy.

The structure of the color data can be seen below.

Time to Code

The packages that we mainly use are:

NumPy

Matplotlib

OpenCV

Image by Author

Import the Packages

Read the Image

The above function reads the image either in grayscale or RGB and returns the image matrix.

Code Implementation with Library

For adding/drawing borders around the image, the important arguments can be named as below:

image_file → Image file location or image name if the image is stored in the same directory.

→ Image file location or image name if the image is stored in the same directory. bt → Border thickness

→ Border thickness color_name → By default it takes 0 (black color). Otherwise, any color name can be taken.

We use the method copyMakeBorder() available in the library OpenCV that is used to create a new bordered image with a specified thickness. In the code, we make sure to convert the color name into values from the color data we collected earlier.

The below function works for both RGB image and grayscale image as expected.

Let’s test the above function —

Image by Author

Image by Author

We can clearly see the borders are been added/drawn. For the grayscale image, though we have mentioned pink, a black border is drawn.

Code Implementation from Scratch

When we talk about the border, it is basically a constant pixel value of one color around the entire image. It is important to take note of the thickness of the border to be able to see. Considering the thickness we should append a constant value around the image that matches the thickness level.

In order to do so, we can use the pad() method available in the library NumPy. This method appends a constant value that matches the level of pad_width argument which is mentioned.

Example

>>> import numpy as np

>>> m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

>>> m = np.array(m)

>>> m

array([[1, 2, 3],

[4, 5, 6],

[7, 8, 9]])

>>>

>>> pm = np.pad(array=m, pad_width=1, mode='constant', constant_values=12)

>>> pm

array([[12, 12, 12, 12, 12],

[12, 1, 2, 3, 12],

[12, 4, 5, 6, 12],

[12, 7, 8, 9, 12],

[12, 12, 12, 12, 12]])

>>>

>>> pmm = np.pad(array=m, pad_width=2, mode='constant', constant_values=24)

>>> pmm

array([[24, 24, 24, 24, 24, 24, 24],

[24, 24, 24, 24, 24, 24, 24],

[24, 24, 1, 2, 3, 24, 24],

[24, 24, 4, 5, 6, 24, 24],

[24, 24, 7, 8, 9, 24, 24],

[24, 24, 24, 24, 24, 24, 24],

[24, 24, 24, 24, 24, 24, 24]])

>>>

More examples you can find in the documentation.

We just need to change the constant_values argument by taking the actual color value.

For a grayscale image, we simply pad the image matrix with black color i.e., 0.

For the RGB image, we are to grab the color value from the data collected, split the image into 3 matrices, and pad each matrix with each color value.

The below function would explain the flow more clearly.

Let’s test the above function —

Image by Author

Image by Author

Yay! We did it. We coded the entire thing including color choice completely from scratch except for the part where we read the image file. We relied mostly on NumPy as it is very fast in computing matrix operations (We could have done it with for loops if we wanted our code to execute very slow).

Personally, this was great learning for me. I am starting to think about how difficult and fun that would be for the people who actually work on open source libraries.

You should definitely check out my other articles on the same subject in my profile.