5

我有两个形状的 numpy 数组(256、256、4)。我想将第四个 256 x 256 平面视为 alpha 级别,并导出已覆盖这些数组的图像。

代码示例:

import numpy as np
from skimage import io

fg = np.ndarray((256, 256, 4), dtype=np.uint8)
one_plane = np.random.standard_normal((256, 256)) * 100 + 128
fg[:,:,0:3] = np.tile(one_plane, 3).reshape((256, 256, 3), order='F')
fg[:, :, 3] = np.zeros((256, 256), dtype=np.uint8)
fg[0:128, 0:128, 3] = np.ones((128, 128), dtype=np.uint8) * 255
fg[128:256, 128:256, 3] = np.ones((128, 128), dtype=np.uint8) * 128

bg = np.ndarray((256, 256, 4), dtype=np.uint8)
bg[:,:,0:3] = np.random.standard_normal((256, 256, 3)) * 100 + 128
bg[:, :, 3] = np.ones((256, 256), dtype=np.uint8) * 255

io.imsave('test_fg.png', fg)
io.imsave('test_bg.png', bg)

这将创建两个图像 fg:

test_fg.png

和背景:

test_bg

我希望能够将 fg 覆盖到 bg 上。也就是说,最终图像的左上角应该是灰色(因为 fg 的 alpha 为 1),右下角是灰色和颜色噪声的混合,其他象限中应该是纯色噪声。我正在寻找类似 add 函数的东西,它给了我一个新的 np 数组。

请注意,我认为这与此答案不同,后者使用 matplotlib.pyplot.plt 覆盖图像并使用彩色地图摆弄。我认为我不需要在这里摆弄彩色地图,但也许答案是我需要。

我希望操作返回一个新的 np.array 的原因是因为我想用许多图像迭代地执行此操作,按顺序叠加。

4

1 回答 1

10

Alpha 混合通常使用 Porter & Duff 方程完成:

在此处输入图像描述

其中srcdst将对应于您的前景和背景图像,并且假定ARGB像素值是浮点,在[0, 1]范围内。

对于您的具体示例:

src_rgb = fg[..., :3].astype(np.float32) / 255.0
src_a = fg[..., 3].astype(np.float32) / 255.0
dst_rgb = bg[..., :3].astype(np.float32) / 255.0
dst_a = bg[..., 3].astype(np.float32) / 255.0

out_a = src_a + dst_a*(1.0-src_a)
out_rgb = (src_rgb*src_a[..., None]
           + dst_rgb*dst_a[..., None]*(1.0-src_a[..., None])) / out_a[..., None]

out = np.zeros_like(bg)
out[..., :3] = out_rgb * 255
out[..., 3] = out_a * 255

输出:

在此处输入图像描述

于 2014-08-07T13:49:39.277 回答