Skip to content

Generare immagini a gradiente con Python e NumPy

Python

Trattando le immagini come array NumPy ndarray, puoi manipolare immagini esistenti o generare nuove immagini usando le funzioni NumPy.

Questo articolo presenta un esempio di generazione di un’immagine sfumata con le funzioni NumPy.

  • np.linspace() e np.tile()
  • Codice di esempio per generare un’immagine sfumata

np.linspace() e np.tile()

se possibili sono vari metodi, in questo articolo creare un’immagine sfumata con il flusso seguente.

  • Genera array 1D che aumentano o diminuiscono a intervalli regolari con numpy.linspace()
  • Disponilo in 2D con numpy.tile()

La direzione del gradiente è solo verticale o orizzontale. Non supporta diagonali o radiali (tondi).

np.linspace()

np.linspace() è una funzione che fornisce un array 1D equistante, dato il valore iniziale start, il valore finale stop e il numero di campioni num.

Una differenza di range() e np.arange(), np.linspace() è conveniente perché calcola automaticamente gli intervalli (passi).

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

Gestirà correttamente se start > stop.

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

Vedere il seguente articolo per i dettagli di np.arange() e np.linspace().

np.tile()

np.tile() è una funzione che dispone l’array verticalmente e orizzontalmente.

È utile per creare l’array che ripete i modelli.

Imposta l’array originale e il numero di iterazioni. Quando si dispone in due dimensioni, il numero di ripetizioni è (il numero di ripetizioni di righe (verticale), il numero di ripetizioni di colonne (orizzontale)).

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

Gli array 2D possono essere gestiti allo stesso modo.

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

Vedere il seguente articolo per ulteriori informazioni su np.tile().

Codice di esempio per generare un’immagine sfumata

Definire una funzione che genera un ndarray 2D che aumenta o aumenta a intervalli uguali nella direzione verticale o orizzontale. Questo ndarray corrisponde a un’immagine gradiente monocromatica (scala di grigi).

Il valore cambia in direzione orizzontale quando is_horizontal è True e in direzione verticale quando False. Per l’orientamento verticale, utilizzare .T per creare una matrice trasposta.

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

Espandilo a tre dimensioni. Imposta start, stop e is_horizontal per ogni colore in un elenco e crea un’immagine gradiente per ogni canale con la funzione per 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 esempio di generazione e salvataggio di un’immagine sfumata è il seguente.

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)

Immagine sfumata grigia NumPy orizzontale

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)

NumPy grigio immagine sfumata verticale

È anche possibile modificare la direzione del gradiente per ciascun RGB.

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)

Immagine sfumata di colore NumPy