使用numpy在网格中显示图像的更惯用的方法 [英] More idiomatic way to display images in a grid with numpy

查看:146
本文介绍了使用numpy在网格中显示图像的更惯用的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有更惯用的方式来显示图像网格,如下面的示例所示?

Is there a more idiomatic way to display a grid of images as in the below example?

import numpy as np

def gallery(array, ncols=3):
    nrows = np.math.ceil(len(array)/float(ncols))
    cell_w = array.shape[2]
    cell_h = array.shape[1]
    channels = array.shape[3]
    result = np.zeros((cell_h*nrows, cell_w*ncols, channels), dtype=array.dtype)
    for i in range(0, nrows):
        for j in range(0, ncols):
            result[i*cell_h:(i+1)*cell_h, j*cell_w:(j+1)*cell_w, :] = array[i*ncols+j]
    return result

我尝试使用hstackreshape等,但是无法获得正确的行为.

I tried using hstack and reshape etc, but could not get the right behaviour.

我对使用numpy进行此操作很感兴趣,因为使用matplotlib调用subplotimshow可以绘制多少图像是有限制的.

I am interested in using numpy to do this because there is a limit to how many images you can plot with matplotlib calls to subplot and imshow.

如果您需要样本数据进行测试,则可以使用网络摄像头,如下所示:

If you need sample data to test you can use your webcam like so:

import cv2
import matplotlib.pyplot as plt
_, img = cv2.VideoCapture(0).read()

plt.imshow(gallery(np.array([img]*6)))

推荐答案

import numpy as np
import matplotlib.pyplot as plt

def gallery(array, ncols=3):
    nindex, height, width, intensity = array.shape
    nrows = nindex//ncols
    assert nindex == nrows*ncols
    # want result.shape = (height*nrows, width*ncols, intensity)
    result = (array.reshape(nrows, ncols, height, width, intensity)
              .swapaxes(1,2)
              .reshape(height*nrows, width*ncols, intensity))
    return result

def make_array():
    from PIL import Image
    return np.array([np.asarray(Image.open('face.png').convert('RGB'))]*12)

array = make_array()
result = gallery(array)
plt.imshow(result)
plt.show()

产量

我们有一个形状为(nrows*ncols, height, weight, intensity)的数组. 我们想要一个形状为(height*nrows, width*ncols, intensity)的数组.

We have an array of shape (nrows*ncols, height, weight, intensity). We want an array of shape (height*nrows, width*ncols, intensity).

因此,这里的想法是首先使用reshape将第一根轴拆分为两个轴,一个轴的长度为nrows,另一个轴的长度为ncols:

So the idea here is to first use reshape to split apart the first axis into two axes, one of length nrows and one of length ncols:

array.reshape(nrows, ncols, height, width, intensity)

这允许我们使用swapaxes(1,2)重新排列轴,以便形状变为 (nrows, height, ncols, weight, intensity).请注意,这会将nrows放在height旁边,并将ncols放在width旁边.

This allows us to use swapaxes(1,2) to reorder the axes so that the shape becomes (nrows, height, ncols, weight, intensity). Notice that this places nrows next to height and ncols next to width.

由于 reshape不会更改数据的排列顺序,因此reshape(height*nrows, width*ncols, intensity)现在会生成所需的数组.

Since reshape does not change the raveled order of the data, reshape(height*nrows, width*ncols, intensity) now produces the desired array.

(从本质上讲)与 unblockshaped函数中使用的思想相同.

This is (in spirit) the same as the idea used in the unblockshaped function.

这篇关于使用numpy在网格中显示图像的更惯用的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆