Efficient conversion from tuple to array?

I am trying to find an efficient way to convert from a tuple (where every 4 entries correspond to R, G, B, alpha pixels) into a NumPy array (for use in OpenCV).

In particular, I use pywin32 to get a bitmap in the client area of ​​the window. This returns as a tuple, where the first four elements belong to the RGB alpha channels of the first pixel, then the next four second pixels, and so on. The tuple itself contains only integer data (i.e., it does not contain any dimension, although I have this information). From this tuple I want to create a NumPy 3D array (width x height x channel). Currently, I just create an array of zeros, and then loop through each entry in the tuple and put it in a NumPy array. I do this using the code below. And I hope that there can be a significantly more efficient way to do this, which I just don't think about. Any suggestions? Thank you very much!

Code:

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 
+6
source share
2 answers

Like Bill above, but rather even faster:

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

array accepts in accordance with the documents: "An array, any object that displays the interface of the array, object, method __array__ returns an array or any (nested) sequence."

asarray takes a few more things: "Input in any form that can be converted to an array. This includes lists, lists of tuples, tuples, tuples of tuples, list tuples, and ndarrays." He takes tuples directly :)

+5
source

Why not just do something like

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

For example, let ('Ri', 'Gi', 'Bi', 'ai') be the color tuple corresponding to pixel i . If you have a large tuple, you can do:

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

Each fragment [:,:,i] for i in [0,4) will provide you with each channel:

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

Source: https://habr.com/ru/post/958521/


All Articles