我是 OpenCV 的新手, 我会很乐意帮助我
我有一个像这样的透明水印图片
我想用 python OpenCV 在多张图片的左下角加上水印
每张图片大小不一
在放置之前我想调整水印的大小以适合图像的大小, Logo 不应按比例缩小或放大
类似于这张图片:
这是我的代码:
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)
但是这段代码我有两个问题
首先,水印位于图片的右上角
其次,水印失去了透明度
图像变成这样
我试试这个:
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)
但是在不同的图片中,每张图片的大小是变化的
因此,必须更改 num1 和 num2
我有点懵, 如何在多张图片的左下角添加水印?
最佳答案
您的问题中的最后一个代码片段就快完成了。您的最终代码大部分都有效,您只需要概括水印所在的坐标。在图像中,左上角是坐标 (0,0)。所以如果你添加下面的代码,你可以计算出一个合适的坐标将水印放在图片的左下角:
(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
此代码允许图像边缘和水印开始之间有一个固定的 50 像素边界。您可能希望使用//将其设置为图像尺寸的一部分,并且您可能希望使用不同的水平和垂直图像偏移量。请注意,此代码目前假定您的所有图像至少比水印大 50 像素(水平和垂直)。
如果你想把它放在图片的右下角,你只需:
num1 = iH - (wH + border)
num2 = iW - (wW + border)
您还提到调整图像大小。我建议你做的是弄清楚你想要水印占据图像的比例,所以假设你想要它至少是图像宽度的十分之一 (1/10) 但你想要保持水印的像素纵横比:
# Resize the watermark
nwW = int(iW // 10)
nwH = int((nwW/wW) * wH)
resized = cv2.resize(watermark, (nwW, nwH), interpolation = cv2.INTER_AREA)
watermark = resized
wW = nwW
wH = nwH
\\10
是“十分之一”设置。也许您需要“三分之一”\\3
或其他内容。 在您计算出水印去向的坐标但在您检索到原始图像/水印尺寸之后执行此操作。如果您正在这样做,您可能还想将 border
设置为图像尺寸的一部分(而不是平坦的 50 像素边框)。
您还询问了如何在多个图像上执行此操作。为此,您可以使用此函数创建一个文件列表(将 .jpg 替换为您的实际图像格式):
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
来自一个答案here .这将为您提供一个文件名列表,您可以迭代这些文件名,并在您使用自己的代码读入后获取每个文件的高度和宽度。
关于python - 在python opencv中的多个图像的左下角放置水印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69201475/