透明なPNGを白い背景にJPEGとして保存

Nov 26 2020

numpy配列としてBGRA画像があり、次のようになっているとします。

[[[233 228 230   128]
  [233 228 230   128]
  [233 228 230   0]
  ...
  [164 160 159   65]
  [199 197 196   65]
  [255 255 254   120]]

これは非常に簡単に見えます-3つのカラーチャネル+1つのアルファがピクセルの透明度を制御します。そのnumpy配列をPNG形式で保存すると、画像は本来の半透明になります。

ただし、JPEGとして保存すると、アルファチャネルは完全に削除され、すべてのピクセルが完全に不透明になります。

JPEGはアルファ透明度をサポートしていないため、半透明の画像(上記のnumpy配列)を代わりに白い背景に保存したいと思います。そうすれば、ピクセルがまだ半透明であるかのように見えます。

完全に白い背景に半透明のnumpy配列をオーバーレイするにはどうすればよいですか?私は主にnumpyとOpenCVを使用しています。

回答

2 MarkSetchell Nov 27 2020 at 10:44

フレッドの答えがうまく示している単純なアルファしきい値よりも、段階的なアルファブレンドを探していると思います。

テスト用に、中央にアルファグラデーションを使用してサンプル画像を作成しました。これは通常の画像であり、Photoshopのように透明度を示すために、チェッカーボード上で合成されています。

アルファブレンディングを行うには、次の式を使用します。

result = alpha * Foreground + (1-alpha)*Background

ここで、値はすべて0..1の範囲でスケーリングされた浮動小数点数です。


黒と白の背景をブレンドするためのコードは次のとおりです。

#!/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)

それは黒の上にこれを与えます:

そしてこれは白の上に:

キーワード:画像処理、Python、OpenCV、アルファ、アルファブレンディング、アルファ合成、オーバーレイ。

1 fmw42 Nov 27 2020 at 06:16

Python OpenCV Numpyでは、アルファチャンネルを画像から分離できます。したがって、imgAがアルファチャネルのある画像である場合。次に、RGB画像(img)とアルファチャネル(alpha)を分離します

img = imgA[:,:,0:3]
alpha = imgA[:,:,3]

次に、imgの色を白に設定します。アルファは黒です。

img[alpha == 0] = (255,255,255)