Mehrere Bilder in einer IPython Notebook-Zelle anzeigen?


72

Wenn ich mehrere Bilder habe (als NumPy-Arrays geladen), wie kann ich die in einer IPython Notebook-Zelle anzeigen?

Ich weiß, dass ich ein Bild plt.imshow(ima)anzeigen kann… aber ich möchte mehr als ein Bild gleichzeitig anzeigen .

Ich habe versucht:

 for ima in images:
     display(Image(ima))

Aber ich bekomme nur einen kaputten Bildlink:

Geben Sie hier die Bildbeschreibung ein


Wenn die Verwendung imshoweine Option ist, warum nicht in Kombination mit subplots, um ein Array von Bildern zu erstellen? Variieren die Bildgrößen stark?
Jakob

Ich könnte Nebenhandlungen verwenden… aber das wird schwierig, wenn ich nur experimentiere: Ich muss die Anzahl der Zeilen und Spalten festlegen. Wenn zu viele Zeilen und Spalten vorhanden sind, muss ich die Figurengröße erhöhen, um sicherzustellen, dass sie jeweils einzeln sind angemessen groß, und ich muss warten, bis die gesamte Figur gerendert ist, bevor ich die einzelnen Bilder sehen kann (im Gegensatz zu ihrer Anzeige, wenn sie generiert werden)
David Wolever

Verwenden Sie Python 3.3? Und ist etwas auf die Konsole geschrieben?
Jakob

Nein - das ist Py2.7. Und was meinst du mit "ist etwas auf die Konsole geschrieben"? Meinst du, wenn ich gehe display(Image(…))? In diesem Fall sieht es so aus, als hätte das Bild so etwas wie src="data:np.array([…])".
David Wolever

Antworten:


104

Kurze Antwort:

Rufen Sie plt.figure()an, um neue Figuren zu erstellen, wenn Sie mehr als eine in einer Zelle haben möchten:

for ima in images:
    plt.figure()
    plt.imshow(ima)

Aber um die Verwirrung zu klären mit Image:

IPython.display.Imageist für die Bildanzeige Dateien , nicht Arraydaten. Wenn Sie numpy-Arrays mit Image anzeigen möchten, müssen Sie diese zuerst in ein Dateiformat konvertieren (am einfachsten mit 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)

Ein Notizbuch, das beide Ansätze veranschaulicht.


2
Subtiler Punkt aus dem verknüpften Notizbuch: Sie müssen dies tun, %matplotlib inlinewenn die Bilder angezeigt werden sollen.
Brent Bradburn

3
Gibt es eine gute Erklärung dafür, warum ich plt.figure()vor jedem Bild muss?
Selam Getachew

Gibt es eine Möglichkeit, das Senden der Bilder auf die Festplatte zu vermeiden? Ich habe eine Reihe von In-Memory-Bildern, die viele Male manipuliert werden - im Speicher .
StephenBoesch

85

Das ist einfacher und funktioniert:

from IPython.display import Image
from IPython.display import display
x = Image(filename='1.png') 
y = Image(filename='2.png') 
display(x, y)

2
Genau das, was ich brauchte - ich habe keine numpy Arrays oder tatsächlichen Plots verwendet, ich hatte nur .pngs zum Anzeigen, und das war perfekt. Vielen Dank!
Dwanderson

12
Dies sollte die akzeptierte Antwort sein. Wenn Sie eine Reihe von Bildern haben, funktioniert dies:display(*images)
Claude

Ich mag das, aber es zeigt Bilder viel größer als plt.imshow(). Es scheint nicht möglich zu sein, die Größe zu kontrollieren .
Tom Hale

71

Horizontales Layout

Demonstration des horizontalen Layouts

Kurze Antwort

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)

Lange Antwort

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)

5
Dies ist eine großartige und nützliche Antwort!
Carlossierra

2
Dies ist eine großartige Möglichkeit, mehrere Zahlen aufzuzählen
Gang Su

16

Mithilfe der Anzeige- und HTML-Funktionen können Sie mehrere Bilder in einer IPython Notebook-Zelle anzeigen. Sie müssen den Satz von HTML-IMG-Tags wie folgt als Zeichenfolge erstellen

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

Ein Anwendungsbeispiel finden Sie unter http://nbviewer.ipython.org/github/PBrockmann/Dodecahedron

Möglicherweise müssen Sie Ihren Browser aktualisieren (Shift + Load), um neue Bilder anzuzeigen, wenn diese aus einer vorherigen Zelle geändert wurden.


Ist es irgendwie möglich, dieses Rendering in einer Datei zu speichern?
Abhijat Biswas

7

Mit IPyPlot können Sie das ganz schnell und einfach tun :

import ipyplot

ipyplot.plot_images(images_array, max_images=20, img_width=150)

Sie würden eine ähnliche Handlung erhalten:
Geben Sie hier die Bildbeschreibung ein

Es verwendet IPython.displayund HTMLunter der Haube und kann Bilder in folgenden Formaten aufnehmen:

  • string Dateipfade
  • PIL.Image Objekte
  • numpy.ndarray Objekte, die Bilder darstellen

Die Anzeige numpy arrayvon 500 Bildern dauert nur wenige Sekunden


3

Wenn Ihnen eine zusätzliche Abhängigkeit nichts ausmacht, finden Sie hier einen Zwei-Liner mit scikit-image :

from skimage.util import montage
plt.imshow(montage(np.array(images), multichannel=True))

Stellen Sie multichannel=Truefür Farbbilder und multichannel=Falsefür Graustufenbilder ein.


2

Irgendwie im Zusammenhang mit dieser Frage (und da ich auf diese Antwort verwiesen wurde, als ich versuchte, sie zu lösen), konnte ich ein ähnliches Problem lösen, indem ich beim Aufrufen einfach den vollständigen Dateipfad eingab Image(). In meinem Fall musste ich ein zufälliges Bild aus verschiedenen in einer Liste gespeicherten Ordnerpfaden auswählen your_folderund anzeigen.

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
Sie sollten Pfade os-agnostisch verwenden os.path.joinoder pathlib.Pathzusammenstellen.
Funky-Future

2

Geben Sie hier die Bildbeschreibung ein

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)

basierend auf @ Michael Antwort


0

basierend auf @ChaosPredictor Antwort

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')

dann

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 Bildraster


0

Die Antworten in diesem Thread haben mir geholfen: Kombinieren Sie mehrere Bilder horizontal mit Python

Das Problem bei der Verwendung von matplotlib war, dass die Definition der angezeigten Bilder wirklich schlecht war. Ich habe dort eine der Antworten an meine Bedürfnisse angepasst:

Der folgende Code zeigt die horizontal in einem Jupyter-Notizbuch verketteten Bilder an. Beachten Sie die kommentierte Zeile mit dem Code, um das Bild zu speichern, wenn Sie dies möchten.

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.