2013-11-20 80 views
6

我試圖找到一種有效的方法來從一個元組(每4個條目對應於一個像素的R,G,B,alpha)轉換爲一個NumPy數組(用於OpenCV)。NumPy - 從元組到數組的高效轉換?

更具體地說,我使用pywin32來獲取窗口的客戶區域位圖。這以元組的形式返回,其中前四個元素屬於第一個像素的RGB-alpha通道,然後是第二個像素的後四個,依此類推。元組本身只包含整數數據(即它不包含任何維度,儘管我確實有這些信息)。從這個元組我想創建NumPy 3D數組(寬x高x通道)。目前,我只是創建一個零數組,然後遍歷元組中的每個條目並將它放在NumPy數組中。我正在使用下面的代碼來做這件事。我希望可以有一個更有效的方式來做到這一點,我只是沒有想到。有什麼建議麼?非常感謝!

代碼:

bitmapBits = dataBitmap.GetBitmapBits(False) #Gets the tuple. 
clientImage = numpy.zeros((height, width, 4), numpy.uint8) 
iter_channel = 0 
iter_x = 0 
iter_y = 0 
for bit in bitmapBits: 
    clientImage[iter_y, iter_x, iter_channel] = bit 
    iter_channel += 1 
    if iter_channel == 4: 
     iter_channel = 0 
     iter_x += 1 
    if iter_x == width: 
     iter_x = 0 
     iter_y += 1 
    if iter_y == height: 
     iter_y = 0 

回答

5

與上述相類似法案,但可能更快:

clientImage = np.asarray(bitmapBits, dtype=np.uint8).reshape(height, width, 4) 

array需要,根據文檔:「一個數組,任何暴露數組接口的對象,其對象的對象,其__array__方法返回一個數組或任何(嵌套)序列。「 「輸入數據,可以轉換爲數組的任何形式,包括列表,元組列表,元組列表,元組元組,元組元組,元組元組,列表元組和元素列表的元組。它直接需要元組:)

+0

這確實稍微快了一點(對於我目前的使用,它比Bill提出的解決方案快了約10%)。 – golmschenk

5

爲什麼不這樣做

import numpy as np 
clientImage = np.array(list(bitmapBits), np.uint8).reshape(height, width, 4) 

例如,讓('Ri', 'Gi', 'Bi', 'ai')是對應於象素i顏色元組。如果你有一個大的元組的這些,你可以這樣做:

In [9]: x = ['R1', 'G1', 'B1', 'a1', 'R2', 'G2', 'B2', 'a2', 'R3', 'G3', 'B3', 'a3', 'R4', 'G4', 'B4', 'a4'] 

In [10]: np.array(x).reshape(2, 2, 4) 
Out[10]: 
array([[['R1', 'G1', 'B1', 'a1'], 
     ['R2', 'G2', 'B2', 'a2']], 

     [['R3', 'G3', 'B3', 'a3'], 
     ['R4', 'G4', 'B4', 'a4']]], 
     dtype='|S2') 

每片[:,:,i]i in [0,4)會給你每個通道:

In [15]: np.array(x).reshape(2, 2, 4)[:,:,0] 
Out[15]: 
array([['R1', 'R2'], 
     ['R3', 'R4']], 
     dtype='|S2')