使用 numpy 在网格中显示图像的更惯用方式

新手上路,请多包涵

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

 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 等,但无法获得正确的行为。

我有兴趣使用 numpy 来执行此操作,因为使用 matplotlib 调用 subplotimshow 可以绘制的图像数量有限。

如果您需要样本数据来测试,您可以像这样使用您的网络摄像头:

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

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

原文由 Frank Wilson 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 657
2 个回答
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)

所以这里的想法是首先使用 reshape 将第一个轴分成两个轴,一个长度 nrows 和一个长度 ncols :

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

这允许我们使用 swapaxes(1,2) 对轴重新排序,使形状变为 (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) 现在生成所需的数组。

这(在精神上)与 unblockshaped 函数 中使用的想法相同。

原文由 unutbu 发布,翻译遵循 CC BY-SA 3.0 许可协议

另一种方法是使用 view_as_blocks 。然后你避免手动交换轴:

 from skimage.util import view_as_blocks
import numpy as np

def refactor(im_in,ncols=3):
    n,h,w,c = im_in.shape
    dn = (-n)%ncols # trailing images
    im_out = (np.empty((n+dn)*h*w*c,im_in.dtype)
           .reshape(-1,w*ncols,c))
    view=view_as_blocks(im_out,(h,w,c))
    for k,im in enumerate( list(im_in) + dn*[0] ):
        view[k//ncols,k%ncols,0] = im
    return im_out

原文由 B. M. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题