note.nkmk.me

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
Sponsored Link

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))
Image.fromarray(np.uint8(array)).save('data/dst/gradation_h.jpg', quality=95)

NumPy gradation image horizontal

array = get_gradation_3d(512, 256, (0, 0, 0), (255, 255, 255), (False, False, False))
Image.fromarray(np.uint8(array)).save('data/dst/gradation_v.jpg', quality=95)

NumPy gradation image vertical

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))
Image.fromarray(np.uint8(array)).save('data/dst/gradation_color.jpg', quality=95)

NumPy gradation image color

Sponsored Link
Share

Related Categories

Related Posts