优化RGBA数组叠加运算(M1 Mac环境)
问题:优化逐像素Alpha的RGBA图像叠加速度
基础信息
- 待处理的两个RGBA数组A、B,形状均为
(42, 28, 4):- 42:y维度
- 28:x维度
- 4:RGBA通道
- 运行设备:2020款M1芯片、16GB内存的MacBook Air
当前实现与性能瓶颈
我希望通过以下逻辑实现逐像素Alpha的图像叠加,但当前速度偏慢——在基础数组上叠加250张图片耗时约20ms,需要优化(最好支持8位Alpha):
def add(A, B): X = A.shape[1] Y = A.shape[0] alpha = A[..., 3] / 255 B[..., :3] = blend(B[..., :3], A[..., :3], alpha.reshape(Y, X, 1)) return B def blend(c1, c2, alpha): return np.asarray((c1 + np.multiply(c2, alpha))/(np.ones(alpha.shape) + alpha), dtype='uint8')
已尝试的优化方案及问题
- 使用
cv2.addWeighted():无法满足需求,该函数只能对整张图使用单一Alpha值,不支持逐像素控制# cv2.addWeighted() in add() ## 无效,因为它对整张图用统一Alpha,而我需要逐像素控制Alpha B = cv.addWeighted(A, 0.5, B, 0.5, 0) - 用
np.vectorize封装blend函数:速度极慢,正如文档所述,它本质只是循环实现# np.vectorize封装blend并在add中使用 ## 速度极慢,文档说明它本质就是循环实现 B[..., :3] = np.vectorize(blend)(A[..., :3], B[..., :3], A[..., 3] / 255) # 修改后的blend函数 def blend(a, b, alpha): if alpha == 0: return b elif alpha == 1: return a return (b + a * alpha) / (1 + alpha) - 将blend逻辑直接移入add函数:叠加效果异常,带Alpha时画面过暗
# 将blend逻辑移到add函数中 ## 叠加效果异常,带Alpha时画面过暗 np.multiply(A, alpha.reshape(Y, X, 1)) + np.multiply(B, 1 - alpha.reshape(Y, X, 1))
其他尝试与需求
我还尝试过一些位运算操作,但无法理解其原理。另外,由于使用M1 Mac,若有Python结合MetalCompute的优化思路,也欢迎提供。
补充测试结果
Christoph Rackwitz提供了一套详尽的优化方案,我在M1设备上的测试结果如下:
2500 calls (numpy) = 0.0807 2500 calls (other) = 0.0833 2500 calls (Christoph´s) = 0.0037
内容的提问来源于stack exchange,提问作者Adril1n
相关产品推荐
相关产品推荐

