How to Downsample Python Array

Muhammad Maisam Abbas Feb 02, 2024
  1. Downsample Array With Slicing in Python3
  2. Downsample Array Using the zoom() Function in Python
  3. Downsample Array With the block_reduce() Function in Python
How to Downsample Python Array

This tutorial will discuss the methods to down-sample an image in Python.

Downsample Array With Slicing in Python3

In Python, an image is a multi-dimensional array. Grayscale images are represented with a 2-dimensional array, while colored or RGB images are represented with a 3-dimensional array.

For the sake of simplicity, this tutorial will focus on reducing the size of 2-dimensional grayscale images, but the methods discussed here can also be used to reduce the size of RGB images.

Our first method is very straightforward. In slicing, as the name suggests, we take a small slice from an overall large image.

While slicing an image, we can give a step parameter that specifies how many values to skip before taking the next value. By default, this value is set to 1.

The following code example demonstrates how we can use array slicing to down-sample an image.

import numpy as np

b = np.arange(0, 100)
c = b.reshape([10, 10])
print("Original Array:")
print(c)
print("Downsized Array:")
print(c[::2, ::2])

Output:

Original Array:
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
Downsized Array:
[[ 0  2  4  6  8]
 [20 22 24 26 28]
 [40 42 44 46 48]
 [60 62 64 66 68]
 [80 82 84 86 88]]

The code written in the above section reduces the size of our original image c from (10, 10) to (5, 5) and stores it into new_c.

An important thing to note is that this method has selected 25 values from our original 100 values. The information in the rest of the values is completely lost in this method.

Downsample Array Using the zoom() Function in Python

The ndimage.interpolation.zoom() function is also used to up-sample or down-sample an image in Python. This function takes 2 parameters; the original image that needs to be zoomed and the zoom ratio.

This method is very similar to the slicing method. It also skips the intermediate values and only selects a few values from our original image while down-sampling.

The following code example demonstrates how we can use the ndimage.interpolation.zoom() function to down-sample an image.

import numpy as np
from scipy import ndimage

b = np.arange(0, 100)
c = b.reshape([10, 10])

new_c = ndimage.interpolation.zoom(c, 0.5)
print("Original Array:")
print(c)
print("Downsized Array:")
print(new_c)

Output:

Original Array:
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
Downsized Array:
[[ 0  2  4  6  8]
 [20 22 24 26 28]
 [40 42 44 46 48]
 [60 62 64 66 68]
 [80 82 84 86 88]]

The code written in the above section works the same way as the previous example and reduces the size of our original image c from (10, 10) to (5, 5).

This method is better than simple slicing because it can also be used to up-sample an image. We have to specify some zoom values greater than 1.

While down-sampling, this method is ineffective because it skips many pixel values and selects only a few from our original image. A more effective method is described below to estimate new values by combining multiple pixel values.

Downsample Array With the block_reduce() Function in Python

Both slicing and zoom methods lead to the staircase effect, which blurs our whole image even when we are down-sampling the input image.

A better approach for handling intermediate values is to estimate them using their surrounding pixels. This can be done in different ways, like interpolation and simple mean.

For the sake of simplicity, we’ll use the simple means method. The block_reduce() function inside the skimage.measure module of python is used to reduce the size of a multi-dimensional array.

This block_reduce() function takes 3 main parameters; the original array, the block size, and the function to be applied on each block.

The block size tells us how many values from our original image will combine to form only one value in our reduced image and the func parameter specifies the function that will be applied to combine all the values in one block.

Since, in all our previous examples, we have been reducing a (10, 10) image to a (5, 5) image, our block size will be (2, 2), and as we want the new value to be the mean of the whole block instead of just one value from the block, we’ll use np.mean as func.

The following code example demonstrates how we can use the block_reduce() method to down-sample our images.

import numpy as np
from skimage.measure import block_reduce

b = np.arange(0, 100)
c = b.reshape([10, 10])

new_c = block_reduce(c, block_size=(2, 2), func=np.mean)
print("Original Array:")
print(c)
print("Downsized Array:")
print(new_c)

Output:

Original Array:
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
Downsized Array:
[[ 5.5  7.5  9.5 11.5 13.5]
 [25.5 27.5 29.5 31.5 33.5]
 [45.5 47.5 49.5 51.5 53.5]
 [65.5 67.5 69.5 71.5 73.5]
 [85.5 87.5 89.5 91.5 93.5]]

The code written in the above section takes a (2, 2) block from our original image c, takes the average of all 4 values inside the block, and places the result into our new image new_c.

This approach is better than the previous two approaches discussed above because it takes the combined effect of all the values instead of just taking 1 value from the original image block and skipping the rest of the 3 values in each block.

Muhammad Maisam Abbas avatar Muhammad Maisam Abbas avatar

Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.

LinkedIn

Related Article - Python Array