OpenCV—python 图像修复(去除水印)

基于OpenCV的两种去水印方案(不具有普适性)
可以使用深度学习方法来去修复图像

一、基于 inpaint 方法(网上的方法,处理质量较低)

算法理论:基于Telea在2004年提出的基于快速行进的修复算法(FMM算法),先处理待修复区域边缘上的像素点,然后层层向内推进,直到修复完所有的像素点
处理方式:由ui人员制作出黑底白色水印且相同位置的水印蒙版图(必须单通道灰度图),然后使用inpaint方法处理原始图像,具体使用时可把水印区放粗,这样处理效果会好点

# -*- coding: utf-8 -*-

"""
cv2.inpaint(src, inpaintMask, 3, cv2.INPAINT_TELEA)
参数:
目标修复图像;
蒙版图(定位修复区域);
选取邻域半径;
修复算法(INPAINT_TELEA:基于快速行进算法 算法效果较好
        INPAINT_NS:基于流体动力学并使用了偏微分方程)
"""

import cv2

src_ = cv2.imread('1111.png')
mask = cv2.imread('2222.png', cv2.IMREAD_GRAYSCALE)
res_ = cv2.resize(src_,None,fx=0.6, fy=0.6, interpolation = cv2.INTER_CUBIC)
mask = cv2.resize(mask,None,fx=0.6, fy=0.6, interpolation = cv2.INTER_CUBIC)
dst = cv2.inpaint(res_, mask, 3, cv2.INPAINT_TELEA)

cv2.imshow('res_', res_)
cv2.imshow('mask', mask)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
测试一张发票图片(不要动歪心思,发票已脱敏)

import cv2
import numpy as np



def Remove_watermark(image):
    hue_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    low_range = np.array([140, 100, 90])
    high_range = np.array([185, 255, 255])
    mask = cv2.inRange(hue_image, low_range, high_range)

    kernel = np.ones((3, 3), np.uint8)
    dilate_img = cv2.dilate(mask, kernel, iterations=1)
    res = cv2.inpaint(image,dilate_img,5,flags=cv2.INPAINT_TELEA)

    cv2.imshow('mask_img',mask)
    cv2.imshow('res', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == '__main__':
    image = cv2.imread('C:\\Users\\xxxx\\Desktop\\piaoju/201920100013253001_30302_01_.jpg')
    Remove_watermark(image)

在这里插入图片描述

二、基于像素的反色中和(处理质量较高)

参考自ps去水印原理,通过一张白底的反色水印图来中和原图水印

# -*- coding: utf-8 -*-
import cv2
import numpy

src = cv2.imread('1111.png')
mask = cv2.imread('2222.png')
src = cv2.resize(src,None,fx=0.6, fy=0.6, interpolation = cv2.INTER_CUBIC)
mask = cv2.resize(mask,None,fx=0.6, fy=0.6, interpolation = cv2.INTER_CUBIC)
save = numpy.zeros(src.shape, numpy.uint8) #创建一张空图像用于保存

for row in range(src.shape[0]):
    for col in range(src.shape[1]):
        for channel in range(src.shape[2]):
            if mask[row, col, channel] == 0:
                val = 0
            else:
                reverse_val = 255 - src[row, col, channel]
                val = 255 - reverse_val * 256 / mask[row, col, channel]
                if val < 0: val = 0
            save[row, col, channel] = val

cv2.imshow('src', src)
cv2.imshow('mask', mask)
cv2.imshow('save', save)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
代码有问题,处理完黑片,不知道哪里出问题了,万望大神不吝赐教

# -*- coding: utf-8 -*-
import numpy as np
from numpy import NaN
import cv2


def __make_mask__(image):
    hue_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    low_range = np.array([140, 100, 90])
    high_range = np.array([185, 255, 255])
    th = cv2.inRange(hue_image, low_range, high_range)
    index1 = th == 255

    mask_img = np.zeros(image.shape, np.uint8)
    mask_img[:, :] = (255, 255, 255)
    mask_img[index1] = image[index1]
    cv2.imshow('mask_img',mask_img)
    cv2.waitKey(0)
    return image,mask_img

def Remove_watermark(image):
    image, mask = __make_mask__(image)
    h, w = image.shape[:2]

    image = [image[:, :, 0], image[:, :, 1], image[:, :, 2]]
    mask =  [mask[:, :, 0],  mask[:, :, 1],  mask[:, :, 2]]
    index = [0,1,2]
    array_255 = np.full((h, w), 255.0, dtype=np.float32)

    result = []
    for i,array,mask in zip(index,image,mask):
        reverse_val = array_255-array
        value = array_255-reverse_val * 256 / mask
        value = np.nan_to_num(value)

        value = np.where(0 < value, 0,value)         # 防止像素溢出
        value = np.where(value > 255, 255,value)     # 防止像素溢出
        value.astype(np.int16)
        cv2.imshow('img'+str(i),value)
        cv2.waitKey(0)
        result.append(value)
    return result


if __name__ == '__main__':
    img_path = 'C:\\Users\\xxxxx\\Desktop\\piaoju/201920100013253001_30302_01_.jpg'

    image = cv2.imread(img_path)
    image = cv2.resize(image, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
    result = Remove_watermark(image)
    result_img = cv2.merge([result[0],result[1],result[2]])
    cv2.imshow('img',image)
    cv2.imshow('result_img',result_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

三、颜色库

在这里插入图片描述

鸣谢
https://my.oschina.net/u/2400083/blog/732321
https://www.cnblogs.com/lgh344902118/p/7928054.html
https://baijiahao.baidu.com/s?id=1624984669133154216&wfr=spider&for=pc
https://blog.csdn.net/Maximun/article/details/85064274

<think>好的,用户想要用Python去除图片或PDF文件中的水印。首先,我需要回忆一下相关的库和方法。对于图片去水印,通常可以使用OpenCV或者PIL来处理,比如通过颜色阈值识别水印区域,然后用修补算法如inpaint来去除。另外,如果水印位置固定,可能直接覆盖或者裁剪也是一种方法。但用户提到的引用中提到了白底黑字的文档场景,这可能意味着水印是简单的文字,位于固定位置,所以可能处理起来相对简单。 然后是PDF去水印。PDF的结构比较复杂,可能包含文本、图片等多种元素。用户提到的引用中有一个函数需要传入原PDF路径、输出路径、横纵像素点和旋转参数,可能是在处理每一页时,将页面转换为图片,然后定位水印的位置并去除。可能需要用到PyMuPDF这样的库来提取页面内容,或者将PDF转换为图片处理后再重新组合成PDF。 接下来需要整理具体的步骤。对于图片去水印,使用OpenCV的inpaint方法,或者用PIL的ImageDraw来覆盖。对于PDF,可能需要先将每一页转换为图像,处理图像中的水印,然后再生成新的PDF。这中间需要注意分辨率的问题,处理后的图片质量可能会影响最终PDF的清晰度。 然后要考虑用户可能的Python库选择。图片处理方面,OpenCV和Pillow都是常用的。PDF处理的话,PyMuPDF(fitz)比较强大,可以提取页面为图片,或者处理文本内容。另外,pdfplumber也可能有用,但可能更适合文本提取。用户提到的引用中提到的函数可能需要使用这些库来逐页处理。 还需要注意不同水印类型的处理方式。如果是文本水印,可能通过检测特定颜色或位置来删除;如果是图片水印,可能需要图像处理技术。但用户的情况是白底黑字的文档,可能水印是半透明的文字,位于页面某个角落,这样可以通过检测特定区域并覆盖白色或其他背景色来去除。 可能的代码示例:对于图片,使用PIL打开图片,定位水印区域,用白色矩形覆盖;对于PDF,用PyMuPDF逐页渲染为图像,处理后再保存为PDF。需要注意处理后的图片合并回PDF时的尺寸和位置是否正确。 同时,用户可能希望有现成的库或者工具,比如提到的pdfwatermark_remover,但需要检查是否存在这样的库。或者需要自己编写脚本,结合图像处理和PDF操作。 最后,需要验证这些方法的可行性,并提醒用户可能遇到的问题,比如水印与正文内容重叠导致去除困难,或者处理后的文档质量下降。此外,性能方面,处理大量页面可能需要较长时间。</think>### Python实现图片/PDF去水印方法 ### 一、图片去水印方法 #### 1. 使用OpenCV修复水印 ```python import cv2 import numpy as np def remove_watermark(img_path, output_path, mask): img = cv2.imread(img_path) dst = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA) cv2.imwrite(output_path, dst) ``` * 原理:通过创建掩膜标记水印区域,使用图像修复算法消除指定区域内容 * 适用场景:复杂背景图片中的局部水印 #### 2. 使用PIL覆盖水印(适用于白底文档) ```python from PIL import Image, ImageDraw def simple_remove(img_path, output_path, position): img = Image.open(img_path) draw = ImageDraw.Draw(img) draw.rectangle(position, fill='white') # 用白色覆盖水印区域 img.save(output_path) ``` * 参数说明:position=(x1,y1,x2,y2) 需预先确定水印坐标范围 * 适用场景:白底文档中的固定位置水印[^2] ### 二、PDF去水印方案 #### 1. 基于PyMuPDF的逐页处理 ```python import fitz # PyMuPDF def pdf_remove_watermark(input_pdf, output_pdf): doc = fitz.open(input_pdf) for page in doc: # 获取页面所有绘制元素 drawings = page.get_drawings() for item in drawings: if is_watermark(item): # 需自定义水印判断逻辑 page.delete_annot(item) doc.save(output_pdf) ``` #### 2. 图片化处理方案(通用性强) ```python def pdf_watermark_remover(input_path, output_path, x_tolerance, y_tolerance, rotation): doc = fitz.open(input_path) for page in doc: pix = page.get_pixmap(matrix=fitz.Matrix(300/72, 300/72)) # 300dpi img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples) # 调用图片去水印函数处理 processed_img = simple_remove(img, (x_tolerance, y_tolerance)) # 将处理后的图片插入新PDF new_page = doc.new_page(width=page.rect.width, height=page.rect.height) new_page.insert_image(page.rect, stream=processed_img.tobytes()) doc.save(output_path) ``` * 优点:可处理各种类型水印 * 缺点:会丢失文本可选择性[^1] ### 三、常用工具库 1. **图片处理** - OpenCV:提供高级图像修复算法 - Pillow:基础图像处理操作 - scikit-image:包含多种图像处理算法 2. **PDF处理** - PyMuPDF:高性能PDF内容操作 - PyPDF2:基础PDF文件操作 - pdfplumber:文本内容分析 ### 四、注意事项 1. 处理前务必备份原始文件 2. 彩色背景文档需调整填充颜色参数 3. 旋转参数需与水印实际角度匹配 4. 高精度处理需适当提升dpi设置(影响处理速度)
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值