Home > Enterprise >  put watermark on bottom left on multiple images in python opencv
put watermark on bottom left on multiple images in python opencv

Time:09-17

I'm new in OpenCV, and I will be happy to help me

I have a transparent watermark image like this

enter image description here

And I want to put watermark on bottom-left corner of multiple images with python OpenCV

each images have difference size

and before put I want to resize the watermark to fit the size of the image, that the logo should not be scaled down or up

something like this image:

enter image description here

and here is my code:

import cv2
img1 = cv2.imread('my_image.png')
img2 = cv2.imread('my_watermark.png')
h, w = img1.shape[:2]

rows,cols,channels = img2.shape

roi = img1[0:rows, 0:cols]


img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)


ret, mask = cv2.threshold(img2gray, 220, 255, cv2.THRESH_BINARY_INV)

mask_inv = cv2.bitwise_not(mask)

img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)

img2_fg = cv2.bitwise_and(img2,img2,mask = mask)

dst = cv2.add(img1_bg,img2_fg)

img1[0:rows, 0: cols] = dst
cv2.imwrite('imglogo.png', img1)

but I have two problems with this code

first, the watermark is located to the top-right on image

Secondly, the watermark loses its transparency

and the image becomes like this

enter image description here

I try this:

image = cv2.imread('my_image.png')
watermark = cv2.imread('my_watermark.png', cv2.IMREAD_UNCHANGED)

(wH, wW) = watermark.shape[:2]
weight = 1 - watermark[:, :, 3] / 255
num1 = 1250
num2 = 50

image[num1:num1   wH, num2:num2   wW, 0] = np.multiply(image[num1:num1   wH, num2:num2   wW, 0], weight).astype(np.uint8)
image[num1:num1   wH, num2:num2   wW, 1] = np.multiply(image[num1:num1   wH, num2:num2   wW, 1], weight).astype(np.uint8)
image[num1:num1   wH, num2:num2   wW, 2] = np.multiply(image[num1:num1   wH, num2:num2   wW, 2], weight).astype(np.uint8)
output = cv2.addWeighted(image[num1:num1   wH, num2:num2   wW], 1, watermark[:, :, 0:3], 1, 1)
image[num1:num1   wH, num2:num2   wW] = output
cv2.imwrite("watermark3.png", image)

but in different images, the size of each image changes

so, num1 and num2 must be changed

I was a little confused, how can I put watermark on bottom-left corner on multiple images?

CodePudding user response:

You are very nearly there with the last code snippet in your question. Your final code mostly works, you just need to generalise the co-ordinates where the watermark goes. In images, the top left corner is co-ordinate (0,0). So if you add the following code, you can work out an appropriate co-ordinate to put the watermark in the bottom left of the image:

(wH, wW) = watermark.shape[:2]
(iH, iW) = image.shape[:2]
border = 50 # allowing a 50 pixel border between the edge of the image and the start of the watermark. 
num1 = iH - (wH   border)
num2 = border

This code allows a fixed 50 pixel border between image edge and watermark start. You might want to use // to set this as a fraction of the image dimensions instead and you might want to use different horizontal and vertical image offsets. Be warned that this code as it stands right now assumes that all your images are at least 50 pixels bigger than your watermark (horizontally and vertically). I am not sure what you mean by not resizing the watermark to fit the image.

If you wanted it at the bottom right of your image, you would simply have:

num1 = iH - (wH   border)
num2 = iW - (wW   border)

You also asked how you would do it on multiple images. For that, you might use this function to create a file list (swap .jpg for whatever your image format actually is):

import os

#Useful function
def createFileList(myDir, format='.jpg'):
fileList = []
print(myDir)
for root, dirs, files in os.walk(myDir, topdown=False):
    for name in files:
        if name.endswith(format):
            fullName = os.path.join(root, name)
            fileList.append(fullName)
return fileList

It comes from an answer enter image description here

  • Related