Skip to content

Générer une image à gradient avec Python, NumPy

En traitant les images comme un tableau NumPy ndarray, vous pouvez manipuler des images existantes ou générer de nouvelles images à l’aide des fonctions NumPy.

Cet article présente un exemple de génération d’une image dégradée avec les fonctions NumPy.

  • np.linspace() et np.tile()
  • Exemple de code pour générer une image dégradée

np.linspace() et np.tile()

Bien que diverses méthodes soient envisageables, dans cet article, créez une image dégradée par le flux suivant.

  • Générez des tableaux 1D qui augmentent ou diminuent à intervalles réguliers avec numpy.linspace()
  • Arrangez-le en 2D avec numpy.tile()

La direction du dégradé est uniquement verticale ou horizontale. Il ne prend pas en charge la diagonale ou la radiale (ronde).

np.linspace()

np.linspace() est une fonction qui renvoie un tableau 1D équidistant, étant donné la valeur de départ start, la valeur de fin stop et le nombre d’échantillons num.

Contrairement à range() et np.arange(), np.linspace() est pratique car il calcule automatiquement les intervalles (étapes).

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. ]

Il fonctionnera correctement si start > stop.

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

Consultez l’article suivant pour plus de détails sur np.arange() et np.linspace().

np.tile()

np.tile() est une fonction qui organise le tableau verticalement et horizontalement.

Il est utile pour créer le tableau qui répète les motifs.

Définissez le tableau d’origine et le nombre d’itérations. Lors de la disposition en deux dimensions, le nombre de répétitions est (le nombre de répétitions de lignes (verticales), le nombre de répétitions de colonnes (horizontales)).

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]]

Les tableaux 2D peuvent être traités de la même manière.

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]]

Consultez l’article suivant pour plus d’informations sur np.tile().

Exemple de code pour générer une image dégradée

Définissez une fonction qui génère un ndarray 2D qui augmente ou diminue à intervalles égaux dans la direction verticale ou horizontale. Ce ndarray correspond à une image dégradée monochrome (niveaux de gris).

La valeur change dans le sens horizontal lorsque is_horizontal est True et dans le sens vertical lorsque False. Pour l’orientation verticale, utilisez .T pour créer une matrice transposée.

def get_gradient_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

Développez cela en trois dimensions. Définissez start, stop et is_horizontal pour chaque couleur dans une liste et créez une image dégradée pour chaque canal avec la fonction pour 2D.

def get_gradient_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_gradient_2d(start, stop, width, height, is_horizontal)

    return result

Un exemple de génération et d’enregistrement d’une image dégradée est le suivant.

from PIL import Image

array = get_gradient_3d(512, 256, (0, 0, 0), (255, 255, 255), (True, True, True))
Image.fromarray(np.uint8(array)).save('data/dst/gray_gradient_h.jpg', quality=95)

Image dégradée grise NumPy horizontale

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

Image dégradée grise NumPy verticale

Il est également possible de changer la direction du dégradé pour chaque RVB.

array = get_gradient_3d(512, 256, (0, 0, 192), (255, 255, 64), (True, False, False))
Image.fromarray(np.uint8(array)).save('data/dst/color_gradient.jpg', quality=95)

Image dégradée de couleur NumPy