当前位置: 首页 > news >正文

python批量去除图片文字水印

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# 需要安装的库
# pip install paddlepaddle -i https://mirrors.aliyun.com/pypi/simple/
# pip install paddleocr -i https://mirrors.aliyun.com/pypi/simple/
# pip install cv2 -i https://mirrors.aliyun.com/pypi/simple/
# pip install numpy -i https://mirrors.aliyun.com/pypi/simple/
# pip install Pillow -i https://mirrors.aliyun.com/pypi/simple/
 
import os
import cv2
import numpy as np
from PIL import Image
from paddleocr import PaddleOCR, draw_ocr
 
 
class DeleteImageWatermark:
    def __init__(self):
        pass
     
    def distinguish_string(self, img_path, lang='ch'):
        """
        得到文字识别结果列表
        img_path: 图片路径
        lang: 默认为识别中文
        return: 返回所有被识别到的文字文本框坐标、文字内容和置信度
        如:[
            [[[1415.0, 977.0], [1482.0, 977.0], [1482.0, 1001.0], [1415.0, 1001.0]], ('小红书', 0.868567168712616)],
            [[[1441.0, 1001.0], [1493.0, 1001.0], [1493.0, 1024.0], [1441.0, 1024.0]], ('小红书', 0.9620211124420166)]
        ]
        """
        orc = PaddleOCR(use_angle_cls=True, lang=lang)
        result = orc.ocr(img_path, cls=True)
        return result
     
    def save_distinguish_result(self, result, img_path, save_path):
        """
        将识别文字的结果输出图片
        """
        image = Image.open(img_path).convert('RGB')
        boxes = [line[0] for line in result]
        txts = [line[1][0] for line in result]
        scores = [line[1][1] for line in result]
        im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf')
        im_show = Image.fromarray(im_show)
        im_show.save(save_path)
     
    def delete_watermark(self, result_list, kw_list, img_path, delete_path):
        """
        将符合目标的水印,模糊化处理
        """
        # 获取所有符合目标的文本框位置
        text_axes_list = []
        for line in result_list:
            for kw in kw_list:
                if kw in line[1][0]:
                    min_width = int(min(line[0][0][0], line[0][3][0]))
                    max_width = int(max(line[0][1][0], line[0][2][0]))
                    min_hight = int(min(line[0][0][1], line[0][1][1]))
                    max_hight = int(max(line[0][2][1], line[0][3][1]))
                    text_axes_list.append([min_width, min_hight, max_width, max_hight])
                    break
        # 去除水印
        delt = 10  # 文本框范围扩大
        img = cv2.imread(img_path, 1)
        tmp_delete_path = delete_path.split('.')[0] + '_test.' + delete_path.split('.')[1]  # 临时图片地址
        cv2.imwrite(tmp_delete_path, img)
        for text_axes in text_axes_list:
            img = cv2.imread(tmp_delete_path, 1)
            hight, width = img.shape[0:2]
            # 截取图片
            min_width = text_axes[0] - delt if text_axes[0] - delt >= 0 else 0
            min_hight = text_axes[1] - delt if text_axes[1] - delt >= 0 else 0
            max_width = text_axes[2] + delt if text_axes[2] + delt <= width else width
            max_hight = text_axes[3] + delt if text_axes[3] + delt <= hight else hight
            cropped = img[min_hight:max_hight, min_width:max_width]  # 裁剪坐标为[y0:y1, x0:x1]
            cv2.imwrite(delete_path, cropped)  # 保存截取的图片
            imgSY = cv2.imread(delete_path, 1)
            # 图片二值化处理,把[200,200,200]-[250,250,250]以外的颜色变成0
            start_rgb = 200
            thresh = cv2.inRange(imgSY, np.array([start_rgb, start_rgb, start_rgb]), np.array([250, 250, 250]))
            # 创建形状和尺寸的结构元素
            kernel = np.ones((3, 3), np.uint8)  # 设置卷积核3*3全是1;将当前的数组作为图像类型来进&#12175;各种操作,就要转换到uint8类型
            # 扩展待修复区域
            hi_mask = cv2.dilate(thresh, kernel, iterations=10)  # 膨胀操作,白色区域增大,iterations迭代次数
            specular = cv2.inpaint(imgSY, hi_mask, 5, flags=cv2.INPAINT_TELEA)
            # imgSY:输入8位1通道或3通道图像。
            # hi_mask:修复掩码,8位1通道图像。非零像素表示需要修复的区域。
            # specular:输出与imgSY具有相同大小和类型的图像。
            # 5:算法考虑的每个点的圆形邻域的半径。
            # flags:NPAINT_NS基于Navier-Stokes的方法、Alexandru Telea的INPAINT_TELEA方法
            cv2.imwrite(delete_path, specular)
            # 覆盖图片
            imgSY = Image.open(delete_path)
            img = Image.open(tmp_delete_path)
            img.paste(imgSY, (min_width, min_hight, max_width, max_hight))
            img.save(tmp_delete_path)
        os.remove(delete_path)
        os.rename(tmp_delete_path, delete_path)
     
    def has_kw(self, result_list, kw_list):
        """
        图片是否包含目标水印,返回匹配到的文字列表
        """
        result_str_list = []
        for line in result_list:
            for kw in kw_list:
                if kw in line[1][0]:
                    result_str_list.append(line[1][0])
                    break
        return result_str_list
 
 
def main(kw_list, img_path, result_path):
    """
    kw_list: 需要识别的文字列表
    img_path: 输入的图片地址
    result_path: 输出去水印的结果图片地址
    """
    d = DeleteImageWatermark()
    # 识别文字
    result = d.distinguish_string(img_path)
    for line in result:
        print(line)  # 打印识别结果:识别到的文字文本框坐标、文字内容和置信度
     
    # 显示文字识别结果
    d.save_distinguish_result(result, img_path, os.path.dirname(__file__) + '/test_01.jpg')
     
    # 是否含有指定水印
    result_str_list = d.has_kw(result, kw_list)
    if len(result_str_list) > 0:
        # 删除水印
        d.delete_watermark(result, kw_list, img_path, result_path)
        print('共有 %d 处水印,都已删除成功!' % len(result_str_list))
        return True
    else:
        print('无指定水印!')
        return False
 
 
if __name__ == '__main__':
    # 图片地址
    #path = os.path.dirname(__file__)
    path=os.getcwd()
    img_path = path + '/去除水印.jpg'
    result_path = path + "/result.jpg"
    # 删除指定水印
    kw_list = [ '快手', '抖音', '网易云']
    main(kw_list, img_path, result_path)

相关文章:

python批量去除图片文字水印

#!/usr/bin/env python # -*- coding:utf-8 -*- # 需要安装的库 # pip install paddlepaddle -i https://mirrors.aliyun.com/pypi/simple/ # pip install paddleocr -i https://mirrors.aliyun.com/pypi/simple/ # pip install cv2 -i https://mirrors.aliyun.com/pypi/simple…...

C++ Qt 自制开源科学计算器

C Qt 自制开源科学计算器 项目地址 软件下载地址 目录 0. 效果预览1. 数据库准备2. 按键&快捷键说明3. 颜色切换功能(初版)4. 未来开发展望5. 联系邮箱 0. 效果预览 普通计算模式效果如下&#xff1a; 科学计算模式效果如下&#xff1a; 更具体的功能演示视频见如下链接…...

相机光学(二十八)——感光度(ISO)

感光度又称为ISO&#xff0c;是指相机对光线的敏感程度。ISO值越大&#xff0c;感光度越高&#xff0c;拍出来的照片就会越亮&#xff0c;反之就会越暗。但是ISO过高会使照片噪点也随之变高。感光度&#xff0c;又称为ISO值&#xff0c;是衡量底片对于光的灵敏程度&#xff0c;…...

基于全国产复旦微JFM7K325T+ARM人工智能数据处理平台

复旦微可以配合的ARM平台有&#xff1a;RK3588/TI AM62X/ NXP IMX.8P/飞腾FT2000等。 产品概述 基于PCIE总线架构的高性能数据预处理FMC载板&#xff0c;板卡采用复旦微的JFM7K325T FPGA作为实时处理器&#xff0c;实现各个接口之间的互联。该板卡可以实现100%国产化。 板卡具…...

HarmonyOS Next应用开发之系统概述

一、鸿蒙系统概述 鸿蒙系统可以分为华为鸿蒙系统&#xff08;HUAWEI HarmonyOS&#xff09;和开源鸿蒙系统&#xff08;OpenHarmony&#xff09;&#xff0c;华为鸿蒙系统是基于OpenHarmony基础之上开发的商业版操作系统。他们二者的关系可以用下图来表示&#xff1a; 1.1、…...

RedHat运维-Linux SSH基础2-基于公钥认证

1. 要想配置基于公钥认证的SSH连接&#xff0c;而不是基于密码认证的SSH连接&#xff0c;只需要将自己的公钥传送给对方即可&#xff0c;假如公钥是~/.ssh/id_rsa.pub&#xff0c;对方是centos192.168.197.128&#xff0c;则命令是____________________________________&#x…...

机器学习模型运用在机器人上

机器学习模型在机器人技术中的应用非常广泛&#xff0c;涵盖了从简单的运动控制到复杂的认知和交互功能。以下是几种机器学习模型在机器人上的典型应用&#xff1a; 感知与识别&#xff1a; 计算机视觉&#xff1a;使用卷积神经网络&#xff08;CNNs&#xff09;识别和理解视觉…...

振弦采集仪在大型工程安全监测中的作用与意义

振弦采集仪在大型工程安全监测中的作用与意义 河北稳控科技振弦采集仪是一种用于测量振动频率的仪器&#xff0c;常用于大型工程的安全监测中。它通过采集振弦的振动信号&#xff0c;可以对工程结构的振动特性进行实时监测和分析。振弦采集仪在大型工程安全监测中具有重要的作…...

CVE-2024-36991:Splunk Enterprise任意文件读取漏洞复现 [附POC]

文章目录 CVE-2024-36991:Splunk Enterprise任意文件读取漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现0x06 修复建议CVE-2024-36991:Splunk Enterprise任意文件读取漏洞复现 [附POC] 0x01 前言 免责声明:…...

Python的utils库详解

Python的utils库并不是一个官方标准库&#xff0c;而是指一系列提供实用功能的工具库或模块&#xff0c;这些库或模块通常包含了一系列帮助开发人员加速日常工作、提高开发效率的工具函数或类。由于Python社区的开放性和活跃性&#xff0c;存在多个不同的utils库&#xff0c;每…...

基于 Qt、FFmpeg 和 OpenGL 开发跨平台安卓实时投屏软件 QtScrcpy

文章目录 基于 Qt、FFmpeg 和 OpenGL 开发跨平台安卓实时投屏软件 QtScrcpy项目详细介绍1. 项目背景2. 功能特点3. 关键代码解读1. 引入必要的头文件和初始化函数2. VideoWidget 类的定义3. OpenGL 初始化和绘制函数4. 视频解码和渲染线程5. 主函数示例结语基于 Qt、FFmpeg 和 …...

LabVIEW光谱测试系统

在现代光通信系统中&#xff0c;光谱分析是不可或缺的工具。开发了一种基于LabVIEW的高分辨率光谱测试系统&#xff0c;通过对可调谐激光器、可编程光滤波器和数据采集系统的控制&#xff0c;实现了高效、高精度的光谱测量。 项目背景 随着光通信技术的迅速发展&#xff0c;对…...

SpringBoot使用@RestController处理GET和POST请求

在Spring MVC中&#xff0c;RestController注解的控制器类可以处理多种HTTP请求方法&#xff0c;包括GET和POST。这些请求方法通过特定的注解来映射&#xff0c;比如GetMapping用于GET请求&#xff0c;PostMapping用于POST请求。这些注解是RequestMapping的特定化版本&#xff…...

Kudu分区策略

Kudu表的分区策略主要有三种&#xff1a;范围分区&#xff08;Partition By Range&#xff09;、哈希分区&#xff08;Partition By Hash&#xff09;和高级分区&#xff08;Partition By Hash And Range&#xff09;。这些策略都要求分区字段必须包含在主键中。 范围分区&…...

spring的bean注册

bean注册 第三方jar包的类想添加到ioc中&#xff0c;加不了Component该怎么办呢。 可以使用Bean和Import引入jar包&#xff0c;可以使用maven安装到本地仓库。 修改bean的名字&#xff1a;Bean("aaa")使用ioc的已经存在的bean对象&#xff0c;如Country&#xff1a;p…...

权限控制权限控制权限控制权限控制权限控制

1.权限的分类 视频学习&#xff1a;https://www.bilibili.com/video/BV15Q4y1K79c/?spm_id_from333.337.search-card.all.click&vd_source386b4f5aae076490e1ad9b863a467f37 1.1 后端权限 1. 后端如何知道该请求是哪个用户发过来的 可以根据 cookie、session、token&a…...

JavaWeb系列二十一: 数据交换和异步请求(JSON, Ajax)

文章目录 官方文档JSON介绍JSON快速入门JSON对象和字符串对象转换应用案例注意事项和细节 JSON在java中使用说明JSON在Java中应用场景应用实例1.3.3 Map对象和JSON字符串转换 2. Ajax介绍2.1 Ajax应用场景2.2 传统的web应用-数据通信方式2.3 Ajax-数据通信方式2.4 Ajax文档使用…...

layui项目中的layui.define、layui.config以及layui.use的使用

第一步:创建一个layuiTest项目&#xff0c;结构如下 第二步&#xff1a;新建一个test.js,利用layui.define定义一个模块test,并向外暴露该模块&#xff0c;该模块里面有两个方法method1和method2. 第三步&#xff1a;新建一个test.html&#xff0c;在该页面引入layui.js&#x…...

ChatGPT对话:Scratch编程中一个单词,如balloon,每个字母行为一致,如何优化编程

【编者按】balloon 7个字母具有相同的行为&#xff0c;根据ChatGPT提供的方法&#xff0c;优化了代码&#xff0c;方便代码维护与复用。初学者可以使用7个字母精灵&#xff0c;复制代码到不同精灵&#xff0c;也能完成这个功能&#xff0c;但不是优化方法&#xff0c;也没有提高…...

HTML【详解】超链接 a 标签的四大功能(页面跳转、页内滚动【锚点】、页面刷新、文件下载)

超链接 a 标签主要有以下功能&#xff1a; 跳转到其他页面 <a href"https://www.baidu.com/" target"_blank" >百度</a>href&#xff1a;目标页面的 url 地址或同网站的其他页面地址&#xff0c;如 detail.htmltarget&#xff1a;打开目标页面…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...