Zapisywanie przezroczystego PNG jako JPEG na białym tle
Powiedzmy, że mam obraz BGRA jako numpy
tablicę, która wygląda mniej więcej tak:
[[[233 228 230 128]
[233 228 230 128]
[233 228 230 0]
...
[164 160 159 65]
[199 197 196 65]
[255 255 254 120]]
Wygląda to całkiem prosto - trzy kanały kolorów + jedna alfa kontrolująca przezroczystość pikseli. Zapisanie tej tablicy numpy w formacie PNG powoduje, że obraz jest półprzezroczysty, tak jak powinien.
Jednak podczas zapisywania pliku jako JPEG kanał alfa jest całkowicie pomijany, a wszystkie piksele są całkowicie nieprzezroczyste.
Ponieważ format JPEG nie obsługuje przezroczystości alfa, chciałbym, aby zamiast tego mój półprzezroczysty obraz (powyższa tablica numpy) został zapisany na białym tle. W ten sposób wyglądałoby to tak, jakby piksele nadal były półprzezroczyste.
Jak mogę nałożyć półprzezroczystą tablicę numpy na w pełni białe tło? Używam głównie numpy i OpenCV.
Odpowiedzi
Myślę, że bardziej szukasz stopniowego mieszania alfa niż prostszego progowania alfa, co ładnie pokazuje odpowiedź Freda.
Zrobiłem przykładowy obraz z gradientem alfa pośrodku do celów testowych. Tutaj jest to normalny obraz i złożony na szachownicy, aby pokazać przezroczystość, tak jak robi to Photoshop:


Aby wykonać mieszanie alfa, użyj wzoru:
result = alpha * Foreground + (1-alpha)*Background
gdzie wszystkie wartości są zmiennoprzecinkowe przeskalowane w zakresie 0..1
Kod łączenia na czarnym i białym tle jest następujący:
#!/usr/bin/env python3
import cv2
import numpy as np
# Load image, including gradient alpha layer
im = cv2.imread('GradientAlpha.png', cv2.IMREAD_UNCHANGED)
# Separate BGR channels from A, make everything float in range 0..1
BGR = im[...,0:3].astype(np.float)/255
A = im[...,3].astype(np.float)/255
# First, composite image over black background using:
# result = alpha * Foreground + (1-alpha)*Background
bg = np.zeros_like(BGR).astype(np.float) # black background
fg = A[...,np.newaxis]*BGR # new alpha-scaled foreground
bg = (1-A[...,np.newaxis])*bg # new alpha-scaled background
res = cv2.add(fg, bg) # sum of the parts
res = (res*255).astype(np.uint8) # scaled back up
cv2.imwrite('OverBlack.png', res)
# Now, composite image over white background
bg = np.zeros_like(BGR).astype(np.float)+1 # white background
fg = A[...,np.newaxis]*BGR # new alpha-scaled foreground
bg = (1-A[...,np.newaxis])*bg # new alpha-scaled background
res = cv2.add(fg, bg) # sum of the parts
res = (res*255).astype(np.uint8) # scaled back up
cv2.imwrite('OverWhite.png', res)
To daje to na czarno:

A to na białym:

Słowa kluczowe : przetwarzanie obrazu, Python, OpenCV, alpha, alpha blending, alpha compositing, overlay.
W Python OpenCV Numpy możesz oddzielić kanał alfa od obrazu. Więc jeśli imgA jest obrazem z kanałem alfa. Następnie oddziel obraz rgb (img) i kanał alfa (alfa)
img = imgA[:,:,0:3]
alpha = imgA[:,:,3]
Następnie ustaw kolor img na biały, gdzie alfa jest czarny
img[alpha == 0] = (255,255,255)