0

This has probably been asked before but I couldn't find anything. Is there a efficient way to replace entries in one array with another conditionally?

For example, lets say I have 2 images (3d arrays - (x,y,3)). Lets say I want to replace the pixel value in the first array with the one in the second array, so long as it is not a given value.

Basically this, but with more efficient numpy code if possible:

for i in range(y):    
  for j in range(x):
    if not np.array_equal(arr2[i,j], some_given_rgb_trio):
      arr1[i,j] = arr2[i,j]

Btw, I understand that this is a really dumb and inefficient way to do it. But I'm not too familiar with all that is available to me through numpy and python in general. I apologize if its a bad question.

Edit: The operation is pretty similar to things done when masking, but I can't seem to find what I need in the np.ma module. One I get this mask through some conditional, I basically want to replace the values in one array with the values of the other array, where my mask is true.

Creating the mask would be pretty simple:

mask = np.getmask(np.ma.masked_equal(arr2, some_given_rgb_trio))
arr1[mask == False] = ?? #Should be the corresponding value in arr2

I can get the mask, but I don't know to then apply it back to actually overlay the images in the desired way.

2 Answers 2

0

You could try generating an rgb image with all pixels representing the variable some_given_rgb_trio and then check the whole array agains arr1. Check the following example:

some_given_rgb_trio = [91, 98, 101]
rbg_image = np.zeros_like(arr1)

for i, v in enumerate(some_given_rgb_trio):
    rbg_image[:, :, i] = v

arr1 = np.where(arr1 != rbg_image, arr2, arr1)

In this case, np.where will use values from arr2 when the condition arr1 != rgb_image is True and values from arr1 otherwise.

Sign up to request clarification or add additional context in comments.

4 Comments

I guess you do not have to create new image. Just find indices and use them to change values like this: indices = np.where(np.all(arr1 == (255,255,255), axis=-1))
Yes, that works for obtaining the x,y indices that match the condition. How would you efficiently use these 2d indices to apply values from arr2 to arr1?
i thought of something like arr1 = arr2.copy(), arr1[indices] = some_given_rgb_trio, but I haven't tried it.
Tried it that way and does not work. There is an issue with trying to index a 3d array using 2d indices. So you'd have to either stack the indices to match the shape of arr1 and arr2 or loop over the channels and apply the indices for each channel individually. In the end, both approaches should work.
0

np.where might work:

arr1 = np.where(arr1 == some_given_rgb_trio, arr1, arr2)

Example with gradient images:

a = np.linspace(0, 255, 256*256*3).reshape(256,256,3).astype(np.uint8)
b = np.rot90(a,1)

c = np.where(a < (50,50,50), a, b) 

plt.imshow(c)
plt.show()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.