【问题标题】:Algorithm to create a square matrix given any number of smaller square matrices给定任意数量的较小方阵创建方阵的算法
【发布时间】:2014-02-03 19:05:31
【问题描述】:

我想使用 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 张图片应该是正确的?

【问题讨论】:

    标签: python numpy opencv matrix


    【解决方案1】:

    这是我用来做这类事情的一个 sn-p:

    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)
    

    【讨论】:

    • imgarray = np.reshape(ls, (ls[0].shape[0], ls[0].shape[1], len(ls))),不起作用,在我的情况下,ls 是[a,b,c,d]。 -- 实际上,它确实有效。
    • 好的,所以蒙太奇从(300, 300, 4)的输入创建,其中4代表图片的数量。它返回大小为(5580, 252) 的图像。它是如何工作的?
    • 输入的第一维应该是图片的数量
    【解决方案2】:

    重用来自How do you split a list into evenly sized chunks?的块:

    定义块(l,n): """ 从 l 中产生连续的 n 大小的块。 """ 对于 xrange(0, len(l), n) 中的 i: 产量 l[i:i+n]

    重写你的函数:

    def plotimgs(ls): shp = ls[0].shape[0] # 图片的尺寸 dim = int(np.ceil(sqrt(len(ls)))) # 每行和列的图片数量 emptyimg = (ls[1]*0 + 1)*255 # 用于添加到列表以允许方阵 ls.extend((dim **2 - ls) * [emptyimg]) # 用缺失的图像填充列表 newimg = np.concatenate([np.concatenate(c, axis=0) for c in chunks(ls, dim)], axis=1) cv2.imshow("框架", newimg) cv2.waitKey(10) plotimgs([a,b,d])

    【讨论】:

    • 它抛出“不是整数”错误。还有,你为什么sqrtdim?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多