Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

python - OpenCV Watermark Always comes out White

I'm trying to put a purple watermark on my image, but it always comes out white for some reason. I'm using cv2.addWeighted. It's just barely visible on this image, but I need it to work on mostly white images as well.

Here's the original image and the watermark:

And this is how it comes out after cv2.addWeighted(img_bottom_right, 1, watermark, 1, 0) (it's at the bottom right):

enter image description here

Why is this happening and how can I do it so it comes out like the following?

I made this last one by checking for purple and copying the pixel instead of adding, which was incredibly inefficient.

I tested with another logo to see if that was the issue, but it also came out very faded.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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)

watermarked image

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...