Python - 如何将 for 循环转换为 numpy 数组

Python - How to convert for loop to numpy array

几天来我一直在尝试将其更改为 numpy 数组。这被用来制作透明图像并将其放在当前帧上。

这是 for 循环的代码:

    alpha_frame = frame[:,:,3] / 255.0
    alpha_foreground = foreground[:,:,3] / 255.0

    for color in range(0, 3):
            frame[:,:,color] = alpha_foreground * foreground[:,:,color] + \
                alpha_frame * frame[:,:,color] * (1 - alpha_foreground)

这是我到目前为止尝试过的方法:

    alpha_frame = frame[:,:,3] / 255.0
    alpha_foreground = foreground[:,:,3] / 255.0

    color = np.arange(0,3)
    frame[:,:,color] = alpha_foreground * foreground[:,:,color] + \
    alpha_frame * frame[:,:,color] * (1 - alpha_foreground)
    return frame

这是错误:

frame = alpha_foreground * foreground + \ 
ValueError: operands could not be broadcast together with shapes (480,640) (480,640,4)

怎么了

frame = alpha_foreground * foreground + 
      alpha_frame * frame * (1 - alpha_foreground)

?

所以首先,如果您要寻找的是性能提升,而不是

alpha_frame = frame[:,:,3] / 255.0
alpha_foreground = foreground[:,:,3] / 255.0

for color in range(0, 3):
        frame[:,:,color] = alpha_foreground * foreground[:,:,color] + \
            alpha_frame * frame[:,:,color] * (1 - alpha_foreground)

我会推荐

alpha_foreground = foreground[:,:,3] / 255.0
alpha_frame = (1 - alpha_foreground) * (frame[:,:,3] / 255.0)


for color in range(0, 3):
        frame[:,:,color] = alpha_foreground * foreground[:,:,color] + \
            alpha_frame * frame[:,:,color]

这在循环中节省了逐元素乘法。 然后,如果你想避免循环,它会尝试:

alpha_foreground = np.zeros((4, foreground.shape[0], foreground.shape[1]))
alpha_foreground[:, :, :] = foreground[:,:,3] / 255.0
alpha_foreground = alpha_foreground.transpose((1, 2, 0))

alpha_frame = np.zeros((4, frame.shape[0], frame.shape[1]))
alpha_frame[:, :, :] = frame[:,:,3] / 255.0
alpha_frame = alpha_frame.transpose((1, 2, 0)) * (1 - alpha_foreground)

frame = alpha_foreground * foreground + alpha_frame * frame

numpy 的广播规则使得如果你想在 3D 数组中广播 2D 数组,应该匹配的维度是最后两个。

这是正确的:n*m 广播到 k*n*m

这不是:n*m 广播给 n*m*k

因此,将 n*m 广播到 n*m*k 的最快解决方案是创建一个 k*n*m 空数组,广播 n*m 数组并转置维度。

小心,一个简单的 .transpose() 会将 k*n*m 变成 m*n*k,这不是我们想要的,所以我们必须将一个转置传递给 .transpose()