What you want to do is blend between the two images depending on the alpha channel of the PNG. Where there is more opacity on the logo, you want more of the logo, and where there is more transparency, you want more image. This is simply expressed by the operation img1 * alpha + img2 * (1 - alpha)
. On one hand this seems similar to cv.addWeighted()
where you could specify beta = 1 - alpha
. However cv.addWeighted()
has a constant alpha/beta, where the PNG has an alpha value for each pixel in the image. Therefore you just need to manually calculate this instead of passing it to a function.
If you read in your logo image with cv.IMREAD_UNCHANGED
then you'll get a four channel BGRA image where the fourth channel is the alpha channel (the amount of transparency). If you then get that image to the same size as the image you wish to watermark, then your code can just look like this (mark
is the 4 channel image with the same h/w as img
):
colormark = mark[..., :3]
alpha = mark[..., 3:] / 255
marked = np.uint8(img * (1 - alpha) + colormark * alpha)
Minor note: I used alpha = mark[..., 3:]
instead of mark[..., 3]
so that the alpha channel shape is (h, w, 1) instead of (h, w), which just allows the math operations to broadcast against a 3 channel image.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…