web-dev-qa-db-fra.com

Afficher plusieurs images dans une cellule IPython Notebook?

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é:

enter image description here

53
David Wolever

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.

81
minrk

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)
57
dval

Mise en page horizontale

 Horizontal layout demonstration

Réponse courte

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)

Longue réponse

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)
45
Michael

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.

16
PBrockmann

 enter image description here

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

2
ChaosPredictor

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)
1
Chriss Paul

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)

 matplotlib image grid

0
Harry Moreno

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)
0
Victor Zuanazzi

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.

0
Palmstrom