Si j'ai plusieurs images (chargées en tant que tableaux NumPy), comment puis-je afficher le dans une cellule Notebook IPython?
Je sais que je peux utiliser plt.imshow(ima)
pour afficher un image… mais je souhaite en afficher plusieurs à la fois.
J'ai essayé:
for ima in images:
display(Image(ima))
Mais je viens d'avoir un lien d'image cassé:
Réponse courte:
appelez plt.figure()
pour créer de nouveaux chiffres si vous voulez plus d'un dans une cellule:
for ima in images:
plt.figure()
plt.imshow(ima)
Mais pour clarifier la confusion avec Image
:
IPython.display.Image
sert à afficher Image files, pas les données de tableau. Si vous souhaitez afficher des tableaux numpy avec Image, vous devez d'abord les convertir au format de fichier (le plus simple avec PIL):
from io import BytesIO
import PIL
from IPython.display import display, Image
def display_img_array(ima):
im = PIL.Image.fromarray(ima)
bio = BytesIO()
im.save(bio, format='png')
display(Image(bio.getvalue(), format='png'))
for ima in images:
display_img_array(ima)
A cahier illustrant les deux approches.
C'est plus facile et ça marche:
from IPython.display import Image
from IPython.display import display
x = Image(filename='1.png')
y = Image(filename='2.png')
display(x, y)
plt.figure(figsize=(20,10))
columns = 5
for i, image in enumerate(images):
plt.subplot(len(images) / columns + 1, columns, i + 1)
plt.imshow(image)
import glob
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
%matplotlib inline
images = []
for img_path in glob.glob('images/*.jpg'):
images.append(mpimg.imread(img_path))
plt.figure(figsize=(20,10))
columns = 5
for i, image in enumerate(images):
plt.subplot(len(images) / columns + 1, columns, i + 1)
plt.imshow(image)
Vous pouvez afficher plusieurs images dans une cellule IPython Notebook à l'aide des fonctions d'affichage et HTML. Vous devez créer le jeu de balises html img sous forme de chaîne, comme suit:
from IPython.display import Image, HTML, display
from glob import glob
imagesList=''.join( ["<img style='width: 120px; margin: 0px; float: left; border: 1px solid black;' src='%s' />" % str(s)
for s in sorted(glob('yourimage*.png')) ])
display(HTML(imagesList))
Voir un exemple d'utilisation de http://nbviewer.ipython.org/github/PBrockmann/Dodecahedron
Vous devrez peut-être actualiser votre navigateur (shift + charge) pour voir les nouvelles images si elles ont été modifiées depuis une cellule précédente.
from matplotlib.pyplot import figure, imshow, axis
from matplotlib.image import imread
mypath='.'
hSize = 5
wSize = 5
col = 4
def showImagesMatrix(list_of_files, col=10):
fig = figure( figsize=(wSize, hSize))
number_of_files = len(list_of_files)
row = number_of_files/col
if (number_of_files%col != 0):
row += 1
for i in range(number_of_files):
a=fig.add_subplot(row,col,i+1)
image = imread(mypath+'/'+list_of_files[i])
imshow(image,cmap='Greys_r')
axis('off')
showImagesMatrix(listOfImages,col)
basé sur @Michael answer
D'une certaine manière liée à cette question (et puisque j'ai été dirigé vers cette réponse lorsque j'essayais de la résoudre), j'ai pu résoudre un problème similaire en tapant simplement le chemin complet du fichier lorsque j'ai appelé Image()
. Dans mon cas, je devais choisir une image aléatoire parmi différents chemins de dossiers stockés dans une liste your_folder
et les afficher.
import random, os
for i in range(len(your_folder)):
ra1 = "../"+your_folder[i]+"/"+random.choice(os.listdir(your_folder[i]))
image = Image(ra1)
display(image)
basé sur la réponse de @ChaosPredictor
from matplotlib.pyplot import figure, imshow, axis
from matplotlib.image import imread
def showImagesMatrix(list_of_files, col=10, wSize=5, hSize=5, mypath='.'):
fig = figure(figsize=(wSize, hSize))
number_of_files = len(list_of_files)
row = number_of_files / col
if (number_of_files % col != 0):
row += 1
for i in range(number_of_files):
a=fig.add_subplot(row, col, i + 1)
image = imread(mypath + '/' + list_of_files[i])
imshow(image, cmap='Greys_r')
axis('off')
puis
from pathlib import Path
p = Path('.')
num_images = 30
list_of_image_paths = [str(x) for x in list(p.glob('../input/train/images/*'))[:num_images]]
showImagesMatrix(list_of_image_paths)
# or with named args
showImagesMatrix(list_of_image_paths, wSize=20, hSize=10, col=5)
Les réponses de ce fil m'ont aidé à: Combiner plusieurs images horizontalement avec Python
Le problème de l'utilisation de matplotlib était que la définition des images affichées était vraiment mauvaise. J'ai adapté l'une des réponses à mes besoins:
Le code suivant affiche les images concaténées horizontalement dans un cahier jupyter. Remarquez la ligne commentée avec le code pour enregistrer l'image si vous le souhaitez.
import numpy as np
import PIL
from IPython.display import display
list_im = ['Test1.jpg', 'Test2.jpg', 'Test3.jpg']
imgs = [ PIL.Image.open(i) for i in list_im ]
# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
imgs_comb = np.hstack( (np.asarray( i.resize(min_shape) ) for i in imgs ) )
# save that beautiful picture
imgs_comb = PIL.Image.fromarray( imgs_comb)
#imgs_comb.save( 'combo.jpg' )
display(imgs_comb)
Si une dépendance supplémentaire ne vous dérange pas, voici une ligne double utilisant scikit-image :
from skimage.util import montage
plt.imshow(montage(np.array(images), multichannel=True))
Définissez multichannel=True
pour les images couleur et multichannel=False
pour les images en niveaux de gris.