← 返回首页
图像添加水印
发表时间:2025-02-19 07:25:51
图像添加水印

给图像添加水印是一种常见的图像处理操作,通常用于保护版权或标记图片来源。

1.图像水印

水印类型: - 文字水印:在图像的指定位置绘制文字,文字可以设置字体、大小、颜色、透明度等属性。 - 图片水印:将一幅小图标(如 LOGO)叠加在图像上,并支持设置透明度和位置。

2.OpenCV实现添加水印

以下是一些步骤和示例代码,展示如何使用OpenCV库在图像上添加水印。

  1. 准备水印图像:首先,你需要有一个水印图像。这个图像可以是文本、logo或其他任何你想要作为水印的图像。
  2. 读取主图像和水印图像:使用OpenCV的cv2.imread()函数读取主图像和水印图像。
  3. 创建水印文本(如果需要):如果水印是文本,你可以使用cv2.putText()函数。
  4. 调整水印大小(如果需要):根据主图像的大小调整水印图像或文本的大小,以确保它不会太大或太小。
  5. 将水印添加到主图像上:使用cv2.addWeighted()函数将水印图像添加到主图像上。

2.1 添加文字水印

import cv2
import numpy as np

# 读取主图像
main_image = cv2.imread('./images/jpg/small_bird01.jpg')

# 设置水印文本和位置
watermark_text = 'DeepSeek'
position = (310, 570)  # 文本位置
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.5
color = (255, 255, 255)  # 白色字体,便于演示,可根据需要调整颜色和透明度
thickness = 1

# 将文本添加到主图像上
cv2.putText(main_image, watermark_text, position, font, font_scale, color, thickness, cv2.LINE_AA)

# 显示结果或保存图像
cv2.imshow('Watermarked Image', main_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# cv2.imwrite('watermarked_image.jpg', main_image)  # 如果需要保存图像

2.2 添加图片水印

# coding=utf-8
import cv2
import numpy as np

bottom = cv2.imread('./images/jpg/small_bird01.jpg')
mark = cv2.imread('./images/png/weixin_logo02.png')

# 加水印
def waterMark(src, mask, transparency):
    # 对掩码:转为float型 --> 乘上透明度 --> 地板整数 --> 回到uint8型
    mask = np.floor(mask.astype(np.float32) * transparency).astype(np.uint8)
    dst = cv2.add(src, mask)
    # 防止溢出像素值域
    dst = dst*(dst<=255) + 255*(dst>255)
    # 回到uint8型
    dst = dst.astype(np.uint8)
    return dst

b_rows, b_cols, b_channels = bottom.shape
m_rows, m_cols, m_channels = mark.shape
# 将图片右下角矩形块 替换为 加过水印的矩形块
bottom[b_rows-m_rows:b_rows, b_cols-m_cols:b_cols, ] = waterMark(bottom[b_rows-m_rows:b_rows, b_cols-m_cols:b_cols, ], mark, 0.3)

# 保存水印图片
cv2.imwrite('waterMark.jpg', bottom)
cv2.imshow('waterMark', bottom)
cv2.waitKey(0)
cv2.destroyAllWindows()

2.3 去除水印

使用 OpenCV 库中的 cv2.inpaint 方法去除图片中的水印是一种图像修复技术。这种方法通常适用于去除较小的、规则形状的瑕疵,如水印,但它的效果很大程度上取决于水印的大小、形状以及周围图像的纹理和颜色。

去除水印的步骤: 1. 加载图片:首先,你需要加载包含水印的图片。 2. 创建遮罩:创建一个与原图大小相同的遮罩,其中水印区域标记为白色(或其他高亮颜色),其余部分为黑色。 3. 应用 inpaint 方法:使用 cv2.inpaint 方法,将遮罩和原图作为输入。 4. 显示和保存结果:显示处理后的图片并可选择保存。

cv2.inpaint 支持两种算法:cv2.INPAINT_TELEA 和 cv2.INPAINT_NS。INPAINT_TELEA 通常效果更好,但计算成本更高;INPAINT_NS 计算成本较低,但在某些情况下效果可能不如 TELEA。

代码实现如下:

首先创建一个与原图大小相同的遮罩,其中水印区域标记为白色,如下图所示:

import cv2
import numpy as np

# 读取模板图像
image = cv2.imread('./images/jpg/waterMark_masked.jpg')

image_gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)  # 转换成灰度图

col,row,l = image.shape
print(col,row)

# 初始化一个与原图像等同的矩阵
temp = np.zeros((col,row))
temp = temp.astype(np.uint8)

cv2.imshow('gary', image_gray)
cv2.waitKey(0)

# 查找图像中的矩阵
ret,thresh = cv2.threshold(image_gray, 250, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, 2, 1)

#查找图片中的第一个矩形的位置,算法显然是不对的,
#我们要查找的图片当中最大的矩形。最大的矩形才有可能是那个水印的矩形位置。
#cnt=contours[0]  #取出数组的第一个元素
#x, y, w, h = cv2.boundingRect(cnt)
index = -1  #用来保存找到的最大的矩形在数组中的下标
counter = 0 #计数器
max_h = 0  #找到矩形的宽和高的尺寸
# 筛选矩形轮廓
for contour in contours:
    # 轮廓近似
    perimeter = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.01 * perimeter, True)
    print("------in loop-------")
    x, y, w, h = cv2.boundingRect(contour)
    print(x, y, w, h)
    if h > max_h:
        index = counter
        max_h = h
    # 如果近似后的轮廓有4个顶点,则可能是矩形
    if len(approx) == 4:
        cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)
    #计数器的累加
    counter = counter + 1
# 显示图像
cv2.imshow('Rectangles Detected', image)
# print('contours length:',contours)
print("-------找到水印矩形坐标-------")
#打印水印矩阵的位置。
cnt = contours[index]
x, y, w, h = cv2.boundingRect(cnt)
print("-------找到水印矩形坐标-------")
print(x, y, w, h)

#cv2.imshow('gary', img)
cv2.waitKey(0)

# 显示水印图片
image2 = cv2.imread("./images/jpg/waterMark.jpg")
# image2 = cv2.imread("./imgs/zhongxin.jpg")
temp = np.zeros(image2.shape[:2], np.uint8)

temp[y:y + h, x:x + w] = 255

#dst = cv2.inpaint(image2, temp, 12, cv2.INPAINT_NS) # 使用INPAINT_TELEA算法进行修复
dst = cv2.inpaint(image2, temp, 12, cv2.INPAINT_TELEA)
cv2.imshow('REMOVE_WATERMARK', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

去除水印效果: