opencv 开放式的imshow是正确的,而imwrite是错误的?

omvjsjqw  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(137)

我只想用另一个png图像覆盖一个png图像,cv2.imshow得到了正确的结果,cv2.imwrite得到了奇怪的结果。

coverImg = cv2.imread('./images/cover.png', cv2.IMREAD_UNCHANGED)
back = cv2.imread('./images/back.png', cv2.IMREAD_UNCHANGED)

x_offset = y_offset = 0

y1, y2 = y_offset, y_offset + coverImg.shape[0]
x1, x2 = x_offset, x_offset + coverImg.shape[1]

alpha_s = coverImg[:, :, 3] / 255.0
alpha_l = 1.0 - alpha_s

result = back.copy()

for c in range(0, 3):
    result[y1:y2, x1:x2, c] = (alpha_s * coverImg[y1:y2, x1:x2, c] +
                               alpha_l * result[y1:y2, x1:x2, c])

cv2.imshow("result", result)
res2 = cv2.imwrite("./result.png", result)

result.dtype就是uint8
显示:

写入:

我的背. png

我的封面. png

zfycwa2u

zfycwa2u1#

出现此问题的原因是您正在修改原始背景图像的副本(加载为BGRA),但未修改结果的Alpha通道。由于背景图像大部分是透明的(阴影除外),因此当使用支持Alpha的对象查看时,结果也是透明的。
为了解决这个问题并保持结果部分透明(在适当的地方),你还需要合并alpha通道。由于alpha=0表示完全透明,alpha=255表示完全不透明,我们的目标是保留两个图像的不透明部分,让我们为每个像素取max(foreground_alpha, background_alpha)。这可以使用np.maximum来完成:

result[y1:y2, x1:x2, 3] = np.maximum(coverImg[y1:y2, x1:x2, 3], back[y1:y2, x1:x2, 3])

完整脚本(添加了导入和对cv2.waitKey的调用):

import cv2
import numpy as np

coverImg = cv2.imread('front.png', cv2.IMREAD_UNCHANGED)
back = cv2.imread('back.png', cv2.IMREAD_UNCHANGED)

x_offset = y_offset = 0

y1, y2 = y_offset, y_offset + coverImg.shape[0]
x1, x2 = x_offset, x_offset + coverImg.shape[1]

alpha_s = coverImg[:, :, 3] / 255.0
alpha_l = 1.0 - alpha_s

result = back.copy()

for c in range(0, 3):
    result[y1:y2, x1:x2, c] = (alpha_s * coverImg[y1:y2, x1:x2, c] +
                               alpha_l * result[y1:y2, x1:x2, c])

result[y1:y2, x1:x2, 3] = np.maximum(coverImg[y1:y2, x1:x2, 3], back[y1:y2, x1:x2, 3])

cv2.imshow("result", result)
cv2.waitKey()
res2 = cv2.imwrite("result.png", result)

这将产生:

相关问题