# Generate gradation image with Python, NumPy

Posted: 2019-05-14 / Tags: Python, NumPy, Image Processing

By treating images as NumPy array `ndarray`, it is possible to process existing images or generate new images using functions of NumPy.

Refer to the following post for details for loading and saving of images.

This post introduces an example of generating a gradation image

• `np.tile()` and `np.linspace()`
• Sample code to generate a gradation image

## np.tile() and np.linspace()

Although various methods are conceivable, here, create a gradation image by the following flow.

• Generate 1D arrays that increase or decrease at regular intervals with `numpy.linspace()`
• Arrange it in 2D with `numpy.tile()`

The gradient direction is vertical or horizontal only. It does not support diagonal or radial (round).

### np.linspace()

`np.linspace()` is a function that returns an equally spaced 1D array, given the start value `start`, the end value `stop`, and the number of samples `num`.

Unlike `range()` and `np.arange()`, `np.linspace()` is convenient because it calculates intervals (steps) automatically.

``````import numpy as np

print(np.linspace(0, 10, 3))
# [ 0.  5. 10.]

print(np.linspace(0, 10, 4))
# [ 0.          3.33333333  6.66666667 10.        ]

print(np.linspace(0, 10, 5))
# [ 0.   2.5  5.   7.5 10. ]
``````

It will handle properly if `start > stop`.

``````print(np.linspace(10, 0, 5))
# [10.   7.5  5.   2.5  0. ]
``````

See the following article for details of `np.arange()` and `np.linspace()`.

### np.tile()

`np.tile()` is a function that arranges the array vertically and horizontally.

It is useful for creating the array that repeat patterns.

Set the original array and the number of iterations. When arranging in two dimensions, the number of repetitions is `(the number of repetitions of rows (vertical), the number of repetitions of columns (horizontal))`.

``````import numpy as np

a = np.array([0, 1, 2, 3])

print(np.tile(a, 2))
# [0 1 2 3 0 1 2 3]

print(np.tile(a, (3, 2)))
# [[0 1 2 3 0 1 2 3]
#  [0 1 2 3 0 1 2 3]
#  [0 1 2 3 0 1 2 3]]

print(np.tile(a, (2, 1)))
# [[0 1 2 3]
#  [0 1 2 3]]
``````

2D arrays can be handled in the same way.

``````a = np.array([[11, 12], [21, 22]])

print(np.tile(a, 2))
# [[11 12 11 12]
#  [21 22 21 22]]

print(np.tile(a, (3, 2)))
# [[11 12 11 12]
#  [21 22 21 22]
#  [11 12 11 12]
#  [21 22 21 22]
#  [11 12 11 12]
#  [21 22 21 22]]

print(np.tile(a, (2, 1)))
# [[11 12]
#  [21 22]
#  [11 12]
#  [21 22]]
``````

## Sample code to generate a gradation image

Define a function that generates a 2D `ndarray` that increases or decreases at equal intervals in the vertical or horizontal direction. This `ndarray` corresponds to a monochrome gradation image.

The value changes in the horizontal direction when `is_horizontal` is `True`, and in the vertical direction when `False`. For vertical orientation, use `.T` to create a transposed matrix.

``````def get_gradation_2d(start, stop, width, height, is_horizontal):
if is_horizontal:
return np.tile(np.linspace(start, stop, width), (height, 1))
else:
return np.tile(np.linspace(start, stop, height), (width, 1)).T
``````
source: nplib.py

Expand this to three dimensions. Set `start`, `stop`, and `is_horizontal` for each color in a list, use the function for 2D, and create a gradation image for each channel.

``````def get_gradation_3d(width, height, start_list, stop_list, is_horizontal_list):
result = np.zeros((height, width, len(start_list)), dtype=np.float)

for i, (start, stop, is_horizontal) in enumerate(zip(start_list, stop_list, is_horizontal_list)):
result[:, :, i] = get_gradation_2d(start, stop, width, height, is_horizontal)

return result
``````
source: nplib.py

An example of generating and saving a gradation image is as follows.

``````array = get_gradation_3d(512, 256, (0, 0, 0), (255, 255, 255), (True, True, True))
`````` ``````array = get_gradation_3d(512, 256, (0, 0, 0), (255, 255, 255), (False, False, False))
`````` It is also possible to change the gradation direction for each RGB.

``````array = get_gradation_3d(512, 256, (0, 0, 192), (255, 255, 64), (True, False, False)) 