Skip to content

Créer un montage d’images avec Python, scikit-image (skimage.util.montage)

En utilisant skimage.util.montage() de scikit-image, vous pouvez créer un montage en concaténant plusieurs images de la même taille horizontalement et verticalement.

Cet article décrit le contenu suivant.

  • Utilisation de base de skimage.util.montage()
  • Spécifiez la valeur (couleur) du rembourrage et des zones supplémentaires :fill
  • Spécifiez la mise en page :grid_shape
  • Spécifiez la largeur des bordures :padding_width
  • Appliquer aux images couleur (tableau 3D) :multichannel

Pour plus d’informations sur la concaténation d’images à l’aide de Pillow et OpenCV, consultez l’article suivant. Ces articles expliquent également le cas des différentes tailles d’image.

Notez que la version de scikit-image dans cet article est 0.16.2.

Utilisation de base de skimage.util.montage()

Les trois tableaux à deux dimensions suivants (numpy.ndarray) de la même forme sont utilisés comme exemples. Des exemples utilisant des images couleur (matrices 3D) sont décrits plus loin.

import numpy as np

import skimage.util

a = np.arange(1, 7).reshape(2, 3)
print(a)
# [[1 2 3]
#  [4 5 6]]

b = a * 10
print(b)
# [[10 20 30]
#  [40 50 60]]

c = a * 100
print(c)
# [[100 200 300]
#  [400 500 600]]

En passant une liste de ces tableaux au premier argument de skimage.util.montage(), un tableau concaténé verticalement et horizontalement est renvoyé.

m = skimage.util.montage([a, b, c])
print(m)
# [[  1   2   3  10  20  30]
#  [  4   5   6  40  50  60]
#  [100 200 300 129 129 129]
#  [400 500 600 129 129 129]]

print(m.shape)
# (4, 6)

Dans cet exemple, les trois tableaux sont disposés en disposition 2 x 2, avec la zone supplémentaire (en bas à droite) remplie de 129, la valeur moyenne de tous les tableaux. La mise en page et les valeurs à remplir dans la zone supplémentaire peuvent être définies avec les paramètres décrits ci-dessous.

Dans skimage.util.montage(), la liste des tableaux est traitée comme un numpy.ndarray de forme (K, M, N) composé de K tableaux avec M lignes et N colonnes. Vous pouvez le spécifier dans ce formulaire.

abc = np.array([a, b, c])
print(abc)
# [[[  1   2   3]
#   [  4   5   6]]
# 
#  [[ 10  20  30]
#   [ 40  50  60]]
# 
#  [[100 200 300]
#   [400 500 600]]]

print(abc.shape)
# (3, 2, 3)

print(skimage.util.montage(abc))
# [[  1   2   3  10  20  30]
#  [  4   5   6  40  50  60]
#  [100 200 300 129 129 129]
#  [400 500 600 129 129 129]]

Si chaque tableau n’a pas la même forme, il ne peut pas être converti en numpy.ndarray de (K, M, N) et une erreur est générée.

d = a[:, :2]
print(d)
# [[1 2]
#  [4 5]]

# skimage.util.montage([a, b, c, d])
# ValueError: could not broadcast input array from shape (2,3) into shape (2)

Spécifiez la valeur (couleur) du rembourrage et des zones supplémentaires :fill

Par défaut, la zone supplémentaire est remplie avec la valeur moyenne de tous les tableaux.

m = skimage.util.montage([a, b, c])
print(m)
# [[  1   2   3  10  20  30]
#  [  4   5   6  40  50  60]
#  [100 200 300 129 129 129]
#  [400 500 600 129 129 129]]
print(np.mean(np.array([a, b, c])))
# 129.5

Vous pouvez spécifier une valeur à remplir avec fill.

print(skimage.util.montage([a, b, c], fill=0))
# [[  1   2   3  10  20  30]
#  [  4   5   6  40  50  60]
#  [100 200 300   0   0   0]
#  [400 500 600   0   0   0]]

Spécifiez la mise en page :grid_shape

Par défaut, il concatène dans une mise en page carrée avec le même nombre de lignes et de colonnes.

Vous pouvez spécifier une mise en page avec grid_shape en tant que tuple (nombre de lignes, nombre de colonnes).

print(skimage.util.montage([a, b, c], grid_shape=(1, 3)))
# [[  1   2   3  10  20  30 100 200 300]
#  [  4   5   6  40  50  60 400 500 600]]

print(skimage.util.montage([a, b, c], grid_shape=(3, 1)))
# [[  1   2   3]
#  [  4   5   6]
#  [ 10  20  30]
#  [ 40  50  60]
#  [100 200 300]
#  [400 500 600]]

Si le nombre de lignes * colonnes est inférieur au nombre de tableaux, une erreur est levée.

# print(skimage.util.montage([a, b, c], grid_shape=(1, 2)))
# IndexError: list index out of range

Si le nombre de lignes * colonnes est supérieur au nombre de tableaux, la zone supplémentaire est remplie avec la valeur de fill. Comme mentionné ci-dessus, par défaut, il est rempli avec la valeur moyenne de tous les tableaux.

print(skimage.util.montage([a, b, c], grid_shape=(2, 3)))
# [[  1   2   3  10  20  30 100 200 300]
#  [  4   5   6  40  50  60 400 500 600]
#  [129 129 129 129 129 129 129 129 129]
#  [129 129 129 129 129 129 129 129 129]]

print(skimage.util.montage([a, b, c], grid_shape=(2, 3), fill=0))
# [[  1   2   3  10  20  30 100 200 300]
#  [  4   5   6  40  50  60 400 500 600]
#  [  0   0   0   0   0   0   0   0   0]
#  [  0   0   0   0   0   0   0   0   0]]

Spécifiez la largeur des bordures :padding_width

Vous pouvez spécifier la largeur des bordures en spécifiant padding_width. La valeur par défaut est padding_width=0, il n’y a donc pas de bordure.

print(skimage.util.montage([a, b, c], padding_width=1))
# [[129 129 129 129 129 129 129 129 129]
#  [129   1   2   3 129  10  20  30 129]
#  [129   4   5   6 129  40  50  60 129]
#  [129 129 129 129 129 129 129 129 129]
#  [129 100 200 300 129 129 129 129 129]
#  [129 400 500 600 129 129 129 129 129]
#  [129 129 129 129 129 129 129 129 129]]

La bordure est également remplie avec la valeur de fill.

print(skimage.util.montage([a, b, c], padding_width=1, fill=0))
# [[  0   0   0   0   0   0   0   0   0]
#  [  0   1   2   3   0  10  20  30   0]
#  [  0   4   5   6   0  40  50  60   0]
#  [  0   0   0   0   0   0   0   0   0]
#  [  0 100 200 300   0   0   0   0   0]
#  [  0 400 500 600   0   0   0   0   0]
#  [  0   0   0   0   0   0   0   0   0]]

Appliquer aux images couleur (tableau 3D) :multichannel

Les images couleur sont traitées comme des tableaux tridimensionnels.

Pour gérer les tableaux tridimensionnels avec skimage.util.montage(), définissez multichannel sur True.

import skimage.io
import skimage.util

a = skimage.io.imread('data/src/lena.jpg')
print(a.shape)
# (225, 400, 3)

b = a // 2
c = a // 3

m = skimage.util.montage([a, b, c], multichannel=True)
print(m.shape)
# (450, 800, 3)

skimage.io.imsave('data/dst/skimage_montage_default.jpg', m)

Image originale:

avec

Résultat:

skimage.util.montage() par défaut

Notez que la valeur par défaut est multichannel=False, donc l’omettre entraînera une erreur.

# skimage.util.montage([a, b, c])
# ValueError: Input array has to be either 3- or 4-dimensional

Comme vous pouvez le voir sur l’image de résultat ci-dessus, par défaut, la zone supplémentaire (en bas à droite) est remplie avec la couleur moyenne.

Vous pouvez spécifier n’importe quelle couleur de remplissage avec un tuple de (R, G, B).

m_fill = skimage.util.montage([a, b, c], fill=(255, 128, 0), multichannel=True)

skimage.io.imsave('data/dst/skimage_montage_fill.jpg', m_fill)

skimage.util.montage() remplit

L’utilisation de grid_shape et de padding_width est la même que pour les tableaux à deux dimensions.

m_1_3_pad = skimage.util.montage([a, b, c],
                                 fill=(0, 0, 0),
                                 grid_shape=(1, 3),
                                 padding_width=10,
                                 multichannel=True)

print(m_1_3_pad.shape)
# (245, 1240, 3)

skimage.io.imsave('data/dst/skimage_montage_1_3_pad.jpg', m_1_3_pad)

skimage.util.montage() grid_shape, padding_width