I'm trying to find an efficient way to convert from a tuple (where every 4 entries correspond to R, G, B, alpha of a pixel) to a NumPy array (for use in OpenCV).
More specifically, I'm using pywin32 to get the client area bitmap of a window. This is returned in the form of a tuple where the first four elements belong to the RGB-alpha channels of the first pixel, then the next four of the second pixel, and so on. The tuple itself only contains the integer data (i.e. it does not contain any dimensionality, although, I do have that information). From this tuple I want to create NumPy 3D array (width x height x channel). Currently, I'm simply creating an array of zeros, then walking through every entry in the tuple and putting it in place in the NumPy array. I'm doing this using the code below. And I'm hoping that there may be a significantly more efficient way to do this that I'm just not thinking of. Any suggestions? Thank you 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
If the code can be vectorized, then numpy will most likely be faster than Python tuples.
To convert a tuple of lists into an array, use the np. asarray() function and then flatten the array using the flatten() method to convert it into a one-dimensional array.
NumPy Arrays are faster than Python Lists because of the following reasons: An array is a collection of homogeneous data-types that are stored in contiguous memory locations. On the other hand, a list in Python is a collection of heterogeneous data types stored in non-contiguous memory locations.
To convert a tuple to an array(list) you can directly use the list constructor.
Similar to Bill above, but likely even faster:
clientImage = np.asarray(bitmapBits, dtype=np.uint8).reshape(height, width, 4)
array
takes, according to the docs: "An array, any object exposing the array interface, an object whose __array__
method returns an array, or any (nested) sequence."
asarray
takes a few more things: "Input data, in any form that can be converted to an array. This includes lists, lists of tuples, tuples, tuples of tuples, tuples of lists and ndarrays." It takes tuples directly :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With