使用numpy在网格中显示图像的更惯用的方法 [英] More idiomatic way to display images in a grid with 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
我尝试使用hstack
和reshape
等,但是无法获得正确的行为.
I tried using hstack
and reshape
etc, but could not get the right behaviour.
我对使用numpy进行此操作很感兴趣,因为使用matplotlib调用subplot
和imshow
可以绘制多少图像是有限制的.
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屋!