Merge NumPy arrays by reference

I want to combine two arrays into a new array in O (1). Then I want to change the values ​​in this new array to change the values ​​in the old arrays.

This refers to the Pygame surfarray module, which does not have a function that returns an RGBA array (n * m * 4) - only RGB (n * m * 3) and A (n * m) arrays separately. Ideally, I would create a new "RGBA" array in O (1) that references the "RGB" and "A" arrays. Changing β€œRGBA” would change both β€œRGB” and β€œA”, and so change the surface.

I do not know if this is possible because I cannot think of a way to do this with C. However, I can think of some ideas. For example, perhaps there is a numpy array type that encapsulates some subarrays and internally redirects indexing to the correct value at level C. That would be nice.

+4
source share
2 answers

You can create your own class that will manage the link procedures, as shown in the example below. You must continue to work on this to enable the slice functions with __getslice__ , __add__ , __mul__ , etc.

 import numpy as np a1 = np.arange(1,11) a2 = np.arange(101,111) class Combiner(): def __init__(self, *args): self.arrays = [arg for arg in args] self.lens = [len(arg) for arg in args] def __getitem__(self,i): if i >=0: shift = 0 acc = 0 for j,l in enumerate(self.lens): acc += l if i<acc: return self.arrays[j][i-shift] shift += l if i<0: shift = 0 acc = 0 for j in xrange(len(self.lens)-1,-1,-1): l = self.lens[j] acc -= l if i>=acc: return self.arrays[j][i+shift] shift += l def __setitem__(self,i,v): if i >=0: shift = 0 acc = 0. for j,l in enumerate(self.lens): acc += l if i<acc: self.arrays[j][i-shift] = v return shift += l if i<0: shift = 0 acc = 0 for j in xrange(len(self.lens)-1,-1,-1): l = self.lens[j] acc -= l if i>=acc: self.arrays[j][i+shift] = v return shift += l a3 = Combiner(a1,a2) print a3[-10] # 101 a3[-2] = 22222 a3[ 4] = 11111 print a1 #[ 1 2 3 4 11111 6 7 8 9 10] print a2 #[ 101 102 103 104 105 106 107 108 22222 110] 
+1
source

I'm not sure I fully understood this question. As far as I know, pygame surfaces are in RGBA (more precisely, BGRA) adjacent arrays if you start pygame and such surfaces (note the β€œ32” in each line):

 # display surface DISP = pygame.display.set_mode((window_w, window_h), 0, 32) # some surface window = pygame.Surface((w, h), 0, 32) 

I would also recommend using 32 bits if possible, rather than 24 bits, because 24-bit surfaces are difficult to interact with arrays (I use numpy to store and process image data).
For example, a 24-bit surface should have a number of pixels divisible by 4, if I'm not mistaken.

Like I said, I'm not sure what your last task is, but here's how I do it. For instance. load the image using openCV lib and convert it to a BGRA array:

 # BGR 3d numpy array array (shape = h, w, 3) with image data img = cv2.imread(filename) # BGRA 3d numpy array (shape = h, w, 4) img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) 

Then this function copies all the data in the array to the surface, you just need to be sure that they have the same pixel size:

 # copy array data into a pygame surface def copy_arr(surface, myarray): bv = surface.get_buffer() bv.write(myarray.tostring(), 0) 

But it may be that you wanted to do something else.

0
source

All Articles