在一个IPython Notebook单元格中显示多个图像?

时间:2013-10-19 22:22:37

标签: ipython ipython-notebook

如果我有多个图像(加载为NumPy数组),如何在一个IPython Notebook单元格中显示?

我知道我可以使用plt.imshow(ima)来显示一个图像...但我希望一次显示多个

我试过了:

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

但我只是得到一个破损的图片链接:

enter image description here

11 个答案:

答案 0 :(得分:81)

简短回答:

如果您想在单元格中添加多个数字,请致电plt.figure()创建新数据:

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

但澄清与Image的混淆:

IPython.display.Image用于显示Image 文件,而不是数组数据。如果要使用Image显示numpy数组,则必须先将它们转换为文件格式(最简单的使用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)

notebook说明了这两种方法。

答案 1 :(得分:61)

这更容易且有效:

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

答案 2 :(得分:47)

水平布局

Horizontal layout demonstration

简短回答

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)

答案 3 :(得分:16)

您可以使用显示和HTML功能在一个IPython Notebook单元格中显示多个图像。您需要创建一组html img标记作为字符串,如下所示

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

查看http://nbviewer.ipython.org/github/PBrockmann/Dodecahedron

中的使用示例

您可能需要刷新浏览器(shift + load)以查看新图像 从之前的单元格改变了。

答案 4 :(得分:7)

您可以使用IPyPlot来快速,轻松地做到这一点:

import ipyplot

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

您将获得类似于以下内容的情节:
enter image description here

它在引擎盖下使用IPython.displayHTML,并且可以以下格式拍摄图像:

  • string文件路径
  • PIL.Image对象
  • numpy.ndarray个代表图像的对象

仅需几秒钟即可显示500张图片中的numpy array

答案 5 :(得分:2)

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)

基于@Michael回答

答案 6 :(得分:1)

以某种方式与这个问题有关(因为当我试图解决它时我被引导到这个答案),我只需在调用Image()时输入完整的文件路径就可以解决类似的问题。就我而言,我必须从列表your_folder中存储的不同文件夹路径中选择一个随机图像并显示它们。

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)

答案 7 :(得分:1)

如果您不介意其他依赖性,这里是使用scikit-image的两个衬里:

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

为彩色图像设置multichannel=True,为灰度图像设置multichannel=False

答案 8 :(得分:0)

基于@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')

然后

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

答案 9 :(得分:0)

此主题中的答案对我有帮助:Combine several images horizontally with Python

使用matplotlib的问题是所显示图像的定义确实不好。我根据自己的需要调整了答案之一:

以下代码显示在Jupyter笔记本中水平连接的图像。请注意,如果有需要,请注意带注释的代码行以保存图像。

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)

答案 10 :(得分:0)

今天,我在 google Colab 和 jupyter notebook 中遇到了这个问题,我将在 MNIST 数据集上分享一个简单的解决方案:

for index in range(1,6):
    plt.imshow(train_set.dataset[index], cmap='gray')

输出只显示最后一张图片:

enter image description here

因为两个 IDE 中的单元格都只显示最后一个图像。因此我添加了 plt.show() 来解决这个问题:

for index in range(1,6):
    plt.imshow(train_set.dataset[index], cmap='gray')
    plt.show()

输出:

enter image description here

最后一条评论:我喜欢这种方式,因为我可以将 input() and plot() functions 添加到循环中,不像我尝试过的其他方法。