云小川网

×

Python 快速移除图片水印方法详解

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

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)

关键说明

  • 阈值调整:核心是通过lower_threshold和upper_threshold定位水印区域。 白色半透明水印:用 (200,200,200) ~ (255,255,255) 黑色半透明水印:用 (0,0,0) ~ (50,50,50) 彩色水印:先转换为HSV格式,按颜色通道定位。
  • 修复算法:cv2.INPAINT_TELEA修复效果更自然,适合大多数场景;cv2.INPAINT_NS 速度更快,适合批量处理。
  • 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)

    注意事项

  • 运行环境:需要安装Python3.7+,推荐使用虚拟环境。
  • 效果限制: 半透明、小面积水印:去除效果接近原图; 大面积、遮挡性水印:修复后会有轻微模糊(属于正常现象); 水印覆盖关键细节:无法100%还原(如水印覆盖人脸、文字)。
  • 版权提醒:仅用于处理自己拥有版权的图片,请勿用于侵权场景。
  • 总结

  • 简单半透明水印:优先用方案1(OpenCV阈值+修复),调整阈值即可适配多数场景。
  • 复杂logo/遮挡水印:用方案2(rembg定位+OpenCV修复),效果更优但依赖额外库。
  • 核心逻辑:先定位水印区域(生成掩码),再用图像修复填充掩码区域,还原背景。
  • 统计代码