在日常的图片处理中,去除水印是一项常见的任务,其效果会根据水印类型的不同而有所差异。

1:使用OpenCV进行基础水印移除(适用于半透明水印)
利用图像修复技术(INPAINTing),首先确定水印的位置,然后用周围的像素来填补该区域,适合背景较为简单、水印为半透明文字或图案的情况。
import cv2 import numpy as np def remove_watermark_opencv(input_path, output_path, lower_threshold=(200, 200, 200), upper_threshold=(255, 255, 255)): """ 使用OpenCV去除图片中的半透明水印 :param input_path: 输入图片路径 :param output_path: 输出图片路径 :param lower_threshold: 水印区域的最低像素值(BGR格式) :param upper_threshold: 水印区域的最高像素值(BGR格式) """ # 1. 读取图片 img = cv2.imread(input_path) if img is None: raise ValueError("无法读取图片,请检查路径是否正确") # 2. 转换为灰度图(简化水印定位) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 3. 二值化处理:定位水印区域(调整阈值匹配水印颜色) # 这里的阈值需要根据水印颜色调整,白色水印用(200,255),黑色水印可改为(0,50) _, mask = cv2.threshold(gray, lower_threshold[0], upper_threshold[0], cv2.THRESH_BINARY) # 4. 膨胀操作:扩大水印区域,确保完整覆盖 kernel = np.ones((2, 2), np.uint8) mask = cv2.dilate(mask, kernel, iterations=1) # 5. 图像修复:用周围像素填充水印区域 # INPAINT_TELEA 修复效果更自然,INPAINT_NS 速度更快 result = cv2.inpaint(img, mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA) # 6. 保存结果 cv2.imwrite(output_path, result) print(f"去水印完成,结果已保存到:{output_path}") # 调用示例 if __name__ == "__main__": # 替换为你的图片路径 input_img = "watermark.jpg" output_img = "no_watermark.jpg" # 调整阈值:如果水印是黑色,把lower_threshold改为(0,0,0),upper_threshold改为(50,50,50) remove_watermark_opencv(input_img, output_img)关键说明
2:基于rembg+inpainting的复杂水印去除
对于不透明的logo类水印,可以使用rembg识别水印区域,再结合图像修复技术进行处理(需要安装额外库)。
步骤 1:安装依赖
pip install opencv-python numpy rembg完整代码
import cv2 import numpy as np from rembg import remove def remove_complex_watermark(input_path, output_path): """ 去除复杂水印(如logo、遮挡水印) :param input_path: 输入图片路径 :param output_path: 输出图片路径 """ # 1. 读取原图 img = cv2.imread(input_path) if img is None: raise ValueError("无法读取图片,请检查路径是否正确") # 2. 用rembg去除前景(提取水印区域) # rembg会把透明区域设为黑色,非透明区域保留,适合定位logo类水印 with open(input_path, 'rb') as f: img_data = f.read() removed_data = remove(img_data) removed_img = cv2.imdecode(np.frombuffer(removed_data, np.uint8), cv2.IMREAD_UNCHANGED) # 3. 提取alpha通道,生成水印掩码 if removed_img.shape[-1] == 4: # 有alpha通道 alpha = removed_img[:, :, 3] _, mask = cv2.threshold(alpha, 1, 255, cv2.THRESH_BINARY) # 膨胀掩码,确保覆盖完整水印 kernel = np.ones((3, 3), np.uint8) mask = cv2.dilate(mask, kernel, iterations=2) else: # 无alpha通道时,降级为方案1的阈值法 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, mask = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY) # 4. 图像修复 result = cv2.inpaint(img, mask, inpaintRadius=5, flags=cv2.INPAINT_TELEA) # 5. 保存结果 cv2.imwrite(output_path, result) print(f"复杂水印去除完成,结果已保存到:{output_path}") # 调用示例 if __name__ == "__main__": input_img = "complex_watermark.png" output_img = "no_complex_watermark.png" remove_complex_watermark(input_img, output_img)注意事项
总结