2015-04-29 56 views
2

我有100個小圖像,我想合併成一個大的(10x10)網格圖像用imshow進行顯示。每個圖像(作爲numpy數組)都位於單元對象的變量內。目前,我正在使用連接首先創建垂直條,然後使用連接來連接所有這些條,但似乎有點笨重。有一個更好的方法嗎?我覺得我應該能夠創建一個大小爲最終圖像(800 x 600)的numpy數組,然後將每個圖像放入其中,但是似乎超出了我的能力,無法將我的頭圍繞在句法上。比python中組合多個cv2圖像(numpy數組)的連接速度更快嗎?

def stackImages(im1, im2, axisToStack): 
    newImage = np.concatenate((im1, im2), axis = axisToStack) 
    return newImage 

def compileCells(): 
    #Make a list of strips 
    strips = [(np.zeros((0,cellWidth,3), np.uint8)) for i in range(numberOfCells)] 

    for x in range(numberOfCells): 
     for i in range(numberOfCells): 
      strips[x] = stackImages(cellArray[i+(x*numberOfCells)].image, strips[x], 0) 

    display = strips[0] 
    for c in range(1,numberOfCells): 
     display = stackImages(strips[c], display, 1) 
    return display 
+0

'concatenate'將接受一長串數組,而不僅僅是2. – hpaulj

回答

2

使用NumPy時,拷貝數組可能是一個真正的速度殺手。每次調用 np.concatenate時,將分配新陣列的空間,並將所有舊的 數據複製到新陣列中。提高代碼速度的一種方法是減少複製數量。

所以,如你所說,更快的方法是爲最終的數組分配空間,從一開始 display

display = np.empty((cellHeight*nrows, cellWidth*ncols, 3), dtype=np.uint8) 

,然後從cellArray將數據複製到display只有一次:

for i, j in IT.product(range(nrows), range(ncols)): 
    arr = cellArray[i*ncols+j].image 
    x, y = i*cellHeight, j*cellWidth 
    display[x:x+cellHeight, y:y+cellWidth, :] = arr 

例如,

import numpy as np 
import matplotlib.pyplot as plt 
import itertools as IT 

def compileCells(cellArray, nrows, ncols, cellHeight, cellWidth): 
    display = np.empty((cellHeight*nrows, cellWidth*ncols, 3), dtype=np.uint8) 
    for i, j in IT.product(range(nrows), range(ncols)): 
     # arr = cellArray[i*ncols+j].image # you may need this 
     arr = cellArray[i*ncols+j]   # my simplified cellArray uses this 
     x, y = i*cellHeight, j*cellWidth 
     display[x:x+cellHeight, y:y+cellWidth, :] = arr 
    return display 

cellHeight, cellWidth = 80, 60 
nrows = ncols = numberOfCells = 10 

cellArray = [np.full((cellHeight, cellWidth, 3), i) 
      for i in np.linspace(0, 255, nrows*ncols)] 
display = compileCells(cellArray, nrows, ncols, cellHeight, cellWidth) 
plt.imshow(display) 
plt.show() 

產生

enter image description here

請注意,您的代碼意味着cellArray是對象,它們的image 屬性與NumPy陣列的列表。爲了使上面的示例代碼可運行並且簡單(r), 我已經將cellArray定義爲NumPy數組的列表。 您可能需要取消註釋

# arr = cellArray[i*ncols+j].image 

,並註釋掉

arr = cellArray[i*ncols+j] 

,以滿足您的cellArray定義。


我們來比較一下這兩種方式完成複印量:

使用原來的做法,如果我們說一個圖像數組的大小爲1,然後建立一個strip需要 分配大小的數組所以一個條需要分配總大小爲1 + 2 + ... + 10 = 10(11)/ 2 = 55的數組 。要構建display需要分配總大小爲55的數組 (1 + 2 + ... + 10)= 55 * 55 = 3025.每個空間分配是 伴隨着複製操作。複製量與最終陣列中的單元格數量成正比地增長

相反,如果我們的最終display分配空間只是一次,然後我們只 需要分配總大小爲10 * 10 = 100。這裏,複製的量的增長線性與細胞的數目。

+0

感謝您的深入評論和解決方案。對此,我真的非常感激! – DTC

相關問題