Relatively new to numpy - trying to use it for image-processing; I have an image in the RGBA color-space; the image is mostly transparent w/ a small-object whose transparency I want to change from 255 to 127, without affecting the transparency of surrounding pixels whose alpha is 0. I can index into the array and find all the groups of pixels I want, but am struggling on how to actually change their alpha-channels to 127 w/o affecting the alpha-channels of all the pixels; here is how I am indexing into the array - the things I've tried either do not affect the array or else reassign all the alphas in the entire array to 127:
>>> from PIL import Image
>>> import numpy as np
>>> a = Image.open('a.png')
>>> b = np.array(a)
>>> b.shape
(1080, 1080, 4)
>>> b[b[:,:,3]==255][:,3]
array([255, 255, 255, ..., 255, 255, 255], dtype=uint8)
>>> b[b[:,:,3]==255][:,3] = 127
>>> b[b[:,:,3]==255][:,3]
array([255, 255, 255, ..., 255, 255, 255], dtype=uint8)
Solution:
>>> b[540,540]
array([ 0, 0, 0, 255], dtype=uint8)
>>> alpha = b[:,:,3]
>>> b[alpha==255,3]=127
>>> b[540,540]
array([ 0, 0, 0, 127], dtype=uint8)
CodePudding user response:
It's because double slicing the array will produce a view of the copy of the array. That's why your array will not be updated. Instead, you can put it together in one slice.
b[b[:,:,3]==255,3] = 127
CodePudding user response:
I would do it like this. I am actually changing 128 to 255 because it's easier to display:
#!/usr/bin/env python3
from PIL import Image
import numpy as np
# Make solid red image
im = np.full((100,300,4), [255,0,0,255], np.uint8)
im[20:80, 20:80, 3] = 64 # 25% opaque square on left
im[20:80, 120:180, 3] = 128 # 50% opaque square in centre
im[20:80, 220:280, 3] = 192 # 75% opaque square on right
Image.fromarray(im).save('start.png')
# Now define easy way to refer to alpha channel
alpha = im[:, :, 3]
# Anywhere alpha is 128, change it to 255
alpha[alpha==128] = 255
Image.fromarray(im).save('result.png')