Give the green part as black part with everything else remaining same
/tmp/workspace
~/attachments
python - <<'PY' from PIL import Image from pathlib import Path p=Path('/tmp/workspace/attachments/7d63b512-7e3a-4664-9196-7a32f7072dfe/file_00000000f1008208b494028e8561a437.png') im=Image.open(p).convert('RGB') print(im.size,im.mode) PY
mkdir -p "/tmp/workspace/recolor-keychain/output" && python - <<'PY' from PIL import Image import numpy as np from pathlib import Path src=Path('/tmp/workspace/attachments/7d63b512-7e3a-4664-9196-7a32f7072dfe/file_00000000f1008208b494028e8561a437.png') out=Path('/tmp/workspace/recolor-keychain/output/keychain_black.png') im=np.asarray(Image.open(src).convert('RGB')).astype(np.float32)/255 # RGB to HSV vectorized mx=im.max(axis=2); mn=im.min(axis=2); d=mx-mn h=np.zeros_like(mx) r,g,b=im[:,:,0],im[:,:,1],im[:,:,2] non=d>1e-6 idx=(mx==r)&non; h[idx]=((g[idx]-b[idx])/d[idx])%6 idx=(mx==g)&non; h[idx]=(b[idx]-r[idx])/d[idx]+2 idx=(mx==b)&non; h[idx]=(r[idx]-g[idx])/d[idx]+4 h=h*60 s=np.zeros_like(mx); s[mx>0]=d[mx>0]/mx[mx>0] # Crocheted body only, defined spatially. Green hues exclude yellow lettering and metal. y,x=np.ogrid[:im.shape[0],:im.shape[1]] roi=(x>=350)&(x<=755)&(y>=590)&(y<=965) green=(h>=55)&(h<=170)&(s>=0.18)&(mx>=0.12)&roi # Restrict to hand-crochet connected region by broad rotated-object vicinity; excludes unrelated leaves. # Black with retained local luminance and texture rather than flat fill result=im.copy() luma=0.2126*r+0.7152*g+0.0722*b # compressed tonal range: highlights remain dark gray, shadows stay black v=0.025+0.28*(np.clip(luma,0,1)**0.85) for c in range(3): result[:,:,c][green]=v[green] Image.fromarray(np.uint8(np.clip(result*255,0,255))).save(out,quality=95) print('changed',green.sum(),'pixels',out) PY python - <<'PY' from PIL import Image p='/tmp/workspace/recolor-keychain/output/keychain_black.png' im=Image.open(p) print('verified:', im.size, im.mode) PY
keychain black
Image · PNG