我想用Opencv绘制一些图像,为此我想将图像粘合在一起。
想象一下,我有4张照片。最好的方法是将它们粘贴在2x2图像矩阵中。
a = img; a.shape == (48, 48)
b = img; b.shape == (48, 48)
c = img; c.shape == (48, 48)
d = img; d.shape == (48, 48)
我现在使用np.reshape,它接受[a,b,c,d]之类的列表,然后我手动放置尺寸以获得以下内容:
np.reshape([a,b,c,d], (a.shape*2, a.shape*2)).shape == (96, 96)
当我有3张照片时,问题就开始了。我有点想到我可以取列表长度的平方根,然后是天花板值,它将产生2(np.ceil(sqrt(len([a,b,c]))) == 2
)的方阵矩阵。然后,我必须添加一个白色图像,其中第一个元素的维度到列表中,然后我们就去了。但我认为必须有一种更简单的方法来完成绘图,很可能已在某处定义。
那么,如何轻松地将任意数量的方矩阵组合成一个大的方阵?
编辑:
我想出了以下内容:
def plotimgs(ls):
shp = ls[0].shape[0] # the image's dimension
dim = np.ceil(sqrt(len(ls))) # the amount of pictures per row AND column
emptyimg = (ls[1]*0 + 1)*255 # used to add to the list to allow square matrix
for i in range(int(dim*dim - len(ls))):
ls.append(emptyimg)
enddim = int(shp*dim) # enddim by enddim is the final matrix dimension
# Convert to 600x600 in the end to resize the pictures to fit the screen
newimg = cv2.resize(np.reshape(ls, (enddim, enddim)), (600, 600))
cv2.imshow("frame", newimg)
cv2.waitKey(10)
plotimgs([a,b,d])
不知何故,即使尺寸合适,它实际上也会克隆一些图片:
When I give 4 pictures, I get 8 pictures. When I give 9 pictures, I get 27 pictures. When I give 16 pictures, I get 64 pictures.
所以事实上,不是平方,我得到了图像的第三种力量。但是,例如
plotimg([a]*9)
会给出尺寸为44*3 x 44*3 = 144x144
的照片,对于9张照片应该是正确的吗?
答案 0 :(得分:0)
这是我用来做这类事情的片段:
import numpy as np
def montage(imgarray, nrows=None, border=5, border_val=np.nan):
"""
Returns an array of regularly spaced images in a regular grid, separated
by a border
imgarray:
3D array of 2D images (n_images, rows, cols)
nrows:
the number of rows of images in the output array. if
unspecified, nrows = ceil(sqrt(n_images))
border:
the border size separating images (px)
border_val:
the value of the border regions of the output array (np.nan
renders as transparent with imshow)
"""
dims = (imgarray.shape[0], imgarray.shape[1]+2*border,
imgarray.shape[2] + 2*border)
X = np.ones(dims, dtype=imgarray.dtype) * border_val
X[:,border:-border,border:-border] = imgarray
# array dims should be [imageno,r,c]
count, m, n = X.shape
if nrows != None:
mm = nrows
nn = int(np.ceil(count/nrows))
else:
mm = int(np.ceil(np.sqrt(count)))
nn = mm
M = np.ones((nn * n, mm * m)) * np.nan
image_id = 0
for j in xrange(mm):
for k in xrange(nn):
if image_id >= count:
break
sliceM, sliceN = j * m, k * n
img = X[image_id,:, :].T
M[sliceN:(sliceN + n), sliceM:(sliceM + m)] = img
image_id += 1
return np.flipud(np.rot90(M))
示例:强>
from scipy.misc import lena
from matplotlib import pyplot as plt
img = lena().astype(np.float32)
img -= img.min()
img /= img.max()
imgarray = np.sin(np.linspace(0, 2*np.pi, 25)[:, None, None] + img)
m = montage(imgarray)
plt.imshow(m, cmap=plt.cm.jet)
答案 1 :(得分:0)
重用How do you split a list into evenly sized chunks?中的块:
def chunks(l, n): """ Yield successive n-sized chunks from l. """ for i in xrange(0, len(l), n): yield l[i:i+n]
重写你的功能:
def plotimgs(ls): shp = ls[0].shape[0] # the image's dimension dim = int(np.ceil(sqrt(len(ls)))) # the amount of pictures per row AND column emptyimg = (ls[1]*0 + 1)*255 # used to add to the list to allow square matrix ls.extend((dim **2 - ls) * [emptyimg]) # filling the list with missing images newimg = np.concatenate([np.concatenate(c, axis=0) for c in chunks(ls, dim)], axis=1) cv2.imshow("frame", newimg) cv2.waitKey(10) plotimgs([a,b,d])