2013-11-20 22 views
6

Sto cercando di trovare un modo efficiente per convertire da una tupla (dove ogni 4 voci corrispondono a R, G, B, alfa di un pixel) a un array NumPy (per l'uso in OpenCV).NumPy - Conversione efficiente da tuple a array?

In particolare, sto usando pywin32 per ottenere la bitmap dell'area client di una finestra. Questo viene restituito sotto forma di una tupla in cui i primi quattro elementi appartengono ai canali RGB-alfa del primo pixel, quindi i successivi quattro del secondo pixel e così via. La tupla stessa contiene solo i dati interi (vale a dire non contiene alcuna dimensionalità, sebbene io abbia quell'informazione). Da questa tupla voglio creare un array NumPy 3D (larghezza x altezza x canale). Attualmente sto semplicemente creando una serie di zeri, quindi percorrendo ogni voce della tupla e inserendola nell'array NumPy. Lo sto facendo usando il codice qui sotto. E spero che possa esserci un modo significativamente più efficace per fare ciò a cui non sto pensando. Eventuali suggerimenti? Grazie mille!

Codice:

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 

risposta

5

Simile a Bill sopra, ma probabilmente ancora più veloce:

array accetta, in base ai documenti: "Un array, qualsiasi oggetto che espone l'interfaccia dell'array, un oggetto di cui __array__ il metodo restituisce una matrice o qualsiasi sequenza (nidificata). "

asarray prende un paio di cose: "I dati di ingresso, in qualsiasi forma che può essere convertito in un array, compresi gli elenchi, liste di tuple, tuple, tuple di tuple, tuple di liste e ndarrays." Richiede tuple direttamente :)

+0

Questo è effettivamente leggermente più veloce (per il mio uso attuale è circa il 10% più veloce della soluzione proposta da Bill). – golmschenk

5

Perché non fare qualcosa di simile

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

Ad esempio, supponiamo ('Ri', 'Gi', 'Bi', 'ai') essere la tupla colore corrispondente al PIXEL i. Se si dispone di un grande tupla di questi, si può fare:

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') 

Ogni slice [:,:,i] per i in [0,4) vi darà ogni canale:

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