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

David Wolever
quelle
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.

minrk
quelle
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)
dval
quelle
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)
Michael
quelle
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.

PBrockmann
quelle
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

Karol Żak
quelle
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.

Matěj Šmíd
quelle
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)
Chriss Paul
quelle
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

ChaosPredictor
quelle
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

Harry Moreno
quelle
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)
Victor Zuanazzi
quelle