【python】去除水印的几种方式

1、python调用FFMEPG的delogo函数去除水印

要使用Python调用FFmpeg的delogo filter去除视频水印,你需要使用subprocess模块运行FFmpeg命令。以下是一个简单的Python脚本示例:

import subprocessdef remove_watermark(input_video, output_video, logo_x, logo_y, logo_width, logo_height):# 构建FFmpeg命令command = ['ffmpeg','-i', input_video,'-vf', f'delogo=x={logo_x}:y={logo_y}:w={logo_width}:h={logo_height}',output_video]# 运行FFmpeg命令subprocess.run(command)# 使用函数去除水印
remove_watermark('input.mp4', 'output.mp4', 10, 10, 100, 100)

使用说明视频:https://www.bilibili.com/video/BV1Jg4y1e7JJ/?spm_id_from=pageDriver

2、使用opencv-python库来处理视频帧

要在Python中去除视频水印,可以使用opencv-python库来处理视频帧,并结合图像处理技术,如图像修复或者图层混合。以下是一个简单的示例,演示如何使用OpenCV去除静态图像水印:

import cv2
import numpy as npdef remove_watermark(video_path, watermark_path, output_path):# 读取视频和水印图像cap = cv2.VideoCapture(video_path)watermark = cv2.imread(watermark_path, cv2.IMREAD_UNCHANGED)watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2GRAY)watermark = cv2.GaussianBlur(watermark, (5, 5), 0)# 获取水印的mask_, mask = cv2.threshold(watermark, 1, 255, cv2.THRESH_BINARY_INV)while True:ret, frame = cap.read()if not ret:break# 将水印区域替换为视频帧的背景frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)seamless_clone = cv2.seamlessClone(watermark, frame, mask, center, cv2.NORMAL_CLONE)# 写入去水印后的视频帧output_video.write(seamless_clone)cap.release()output_video.release()# 使用函数去除视频中的水印
remove_watermark('input_video.mp4', 'watermark.png', 'output_video.mp4')

请注意,这个示例使用了seamlessClone函数,它要求水印区域的中心与背景相匹配,并且假设水印背景是纯色或者与视频背景融合得当。如果这些条件不满足,可能需要更复杂的图像处理技术,例如图像修复或深度学习去水印方法。

示例2
下面是使用OpenCV去除水印的Python代码示例:

import cv2
import numpy as np# 读取视频和水印图像
video_path = 'video_with_watermark.mp4'
watermark_path = 'watermark.png'
cap = cv2.VideoCapture(video_path)# 读取视频的宽、高和帧数
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)# 读取水印图像
watermark = cv2.imread(watermark_path, cv2.IMREAD_UNCHANGED)
watermark_gray = cv2.cvtColor(watermark, cv2.COLOR_BGR2GRAY)# 创建输出视频
out = cv2.VideoWriter('video_without_watermark.mp4', cv2.VideoWriter_fourcc(*'XVID'), fps, (frame_width, frame_height))while(cap.isOpened()):ret, frame = cap.read()if ret:# 转换为灰度图像gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 使用cv2.matchTemplate()寻找水印的位置res = cv2.matchTemplate(gray_frame, watermark_gray, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)# 计算水印的位置top_left = max_locbottom_right = (top_left[0] + watermark_gray.shape[1], top_left[1] + watermark_gray.shape[0])# 绘制矩形框覆盖水印cv2.rectangle(frame, top_left, bottom_right, (0, 0, 0), thickness=watermark_gray.shape[0])# 写入去水印后的帧out.write(frame)cv2.imshow('Video', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:breakcap.release()
out.release()
cv2.destroyAllWindows()

3、python实战之去除视频水印&字幕,完整代码

import os
import sys
import cv2
import numpy
from moviepy import editorVIDEO_PATH = 'video'
OUTPUT_PATH = 'output'
TEMP_VIDEO = 'temp.mp4'class WatermarkRemover():def __init__(self, threshold: int, kernel_size: int):self.threshold = threshold  # 阈值分割所用阈值self.kernel_size = kernel_size  # 膨胀运算核尺寸#根据用户手动选择的ROI(Region of Interest,感兴趣区域)框选水印或字幕位置。def select_roi(self, img: numpy.ndarray, hint: str) -> list:'''框选水印或字幕位置,SPACE或ENTER键退出:param img: 显示图片:return: 框选区域坐标'''COFF = 0.7w, h = int(COFF * img.shape[1]), int(COFF * img.shape[0])resize_img = cv2.resize(img, (w, h))roi = cv2.selectROI(hint, resize_img, False, False)cv2.destroyAllWindows()watermark_roi = [int(roi[0] / COFF), int(roi[1] / COFF), int(roi[2] / COFF), int(roi[3] / COFF)]return watermark_roi#对输入的蒙版进行膨胀运算,扩大蒙版的范围def dilate_mask(self, mask: numpy.ndarray) -> numpy.ndarray:'''对蒙版进行膨胀运算:param mask: 蒙版图片:return: 膨胀处理后蒙版'''kernel = numpy.ones((self.kernel_size, self.kernel_size), numpy.uint8)mask = cv2.dilate(mask, kernel)return mask#根据手动选择的ROI区域,在单帧图像中生成水印或字幕的蒙版。def generate_single_mask(self, img: numpy.ndarray, roi: list, threshold: int) -> numpy.ndarray:'''通过手动选择的ROI区域生成单帧图像的水印蒙版:param img: 单帧图像:param roi: 手动选择区域坐标:param threshold: 二值化阈值:return: 水印蒙版'''# 区域无效,程序退出if len(roi) != 4:print('NULL ROI!')sys.exit()# 复制单帧灰度图像ROI内像素点roi_img = numpy.zeros((img.shape[0], img.shape[1]), numpy.uint8)start_x, end_x = int(roi[1]), int(roi[1] + roi[3])start_y, end_y = int(roi[0]), int(roi[0] + roi[2])gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)roi_img[start_x:end_x, start_y:end_y] = gray[start_x:end_x, start_y:end_y]# 阈值分割_, mask = cv2.threshold(roi_img, threshold, 255, cv2.THRESH_BINARY)return mask#通过截取视频中多帧图像生成多张水印蒙版,并通过逻辑与计算生成最终的水印蒙版def generate_watermark_mask(self, video_path: str) -> numpy.ndarray:'''截取视频中多帧图像生成多张水印蒙版,通过逻辑与计算生成最终水印蒙版:param video_path: 视频文件路径:return: 水印蒙版'''video = cv2.VideoCapture(video_path)success, frame = video.read()roi = self.select_roi(frame, 'select watermark ROI')mask = numpy.ones((frame.shape[0], frame.shape[1]), numpy.uint8)mask.fill(255)step = video.get(cv2.CAP_PROP_FRAME_COUNT) // 5index = 0while success:if index % step == 0:mask = cv2.bitwise_and(mask, self.generate_single_mask(frame, roi, self.threshold))success, frame = video.read()index += 1video.release()return self.dilate_mask(mask)#根据手动选择的ROI区域,在单帧图像中生成字幕的蒙版。def generate_subtitle_mask(self, frame: numpy.ndarray, roi: list) -> numpy.ndarray:'''通过手动选择ROI区域生成单帧图像字幕蒙版:param frame: 单帧图像:param roi: 手动选择区域坐标:return: 字幕蒙版'''mask = self.generate_single_mask(frame, [0, roi[1], frame.shape[1], roi[3]], self.threshold)  # 仅使用ROI横坐标区域return self.dilate_mask(mask)def inpaint_image(self, img: numpy.ndarray, mask: numpy.ndarray) -> numpy.ndarray:'''修复图像:param img: 单帧图像:parma mask: 蒙版:return: 修复后图像'''telea = cv2.inpaint(img, mask, 1, cv2.INPAINT_TELEA)return teleadef merge_audio(self, input_path: str, output_path: str, temp_path: str):'''合并音频与处理后视频:param input_path: 原视频文件路径:param output_path: 封装音视频后文件路径:param temp_path: 无声视频文件路径'''with editor.VideoFileClip(input_path) as video:audio = video.audiowith editor.VideoFileClip(temp_path) as opencv_video:clip = opencv_video.set_audio(audio)clip.to_videofile(output_path)def remove_video_watermark(self):'''去除视频水印'''if not os.path.exists(OUTPUT_PATH):os.makedirs(OUTPUT_PATH)filenames = [os.path.join(VIDEO_PATH, i) for i in os.listdir(VIDEO_PATH)]mask = Nonefor i, name in enumerate(filenames):if i == 0:# 生成水印蒙版mask = self.generate_watermark_mask(name)# 创建待写入文件对象video = cv2.VideoCapture(name)fps = video.get(cv2.CAP_PROP_FPS)size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))video_writer = cv2.VideoWriter(TEMP_VIDEO, cv2.VideoWriter_fourcc(*'mp4v'), fps, size)# 逐帧处理图像success, frame = video.read()while success:frame = self.inpaint_image(frame, mask)video_writer.write(frame)success, frame = video.read()video.release()video_writer.release()# 封装视频(_, filename) = os.path.split(name)output_path = os.path.join(OUTPUT_PATH, filename.split('.')[0] + '_no_watermark.mp4')  # 输出文件路径self.merge_audio(name, output_path, TEMP_VIDEO)if os.path.exists(TEMP_VIDEO):os.remove(TEMP_VIDEO)def remove_video_subtitle(self):'''去除视频字幕'''if not os.path.exists(OUTPUT_PATH):os.makedirs(OUTPUT_PATH)filenames = [os.path.join(VIDEO_PATH, i) for i in os.listdir(VIDEO_PATH)]roi = []for i, name in enumerate(filenames):# 创建待写入文件对象video = cv2.VideoCapture(name)fps = video.get(cv2.CAP_PROP_FPS)size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))video_writer = cv2.VideoWriter(TEMP_VIDEO, cv2.VideoWriter_fourcc(*'mp4v'), fps, size)# 逐帧处理图像success, frame = video.read()if i == 0:roi = self.select_roi(frame, 'select subtitle ROI')while success:mask = self.generate_subtitle_mask(frame, roi)frame = self.inpaint_image(frame, mask)video_writer.write(frame)success, frame = video.read()video.release()video_writer.release()# 封装视频(_, filename) = os.path.split(name)output_path = os.path.join(OUTPUT_PATH, filename.split('.')[0] + '_no_sub.mp4')  # 输出文件路径self.merge_audio(name, output_path, TEMP_VIDEO)if os.path.exists(TEMP_VIDEO):os.remove(TEMP_VIDEO)if __name__ == '__main__':sel=input('1:去水印, 2:去字幕\n')if sel=='1':remover = WatermarkRemover(threshold=80, kernel_size=5)remover.remove_video_watermark()if sel=='2':remover = WatermarkRemover(threshold=80, kernel_size=5)remover.remove_video_subtitle()

另外:图片去除水印方法
(一)手机——乐奇爱水印精灵
有点免费去除水印,可以无效其操作,但是每天只能保存一张,好就好在邀请一个人可以活得60此保存机会,那个被邀请的也能获得十次,可以P图。

(二)电脑——quququ.cn
把图片拖到网站,调整画笔大小,抹除文字就可以p图完成,免费下载就可以了。

ps:参考自:https://blog.csdn.net/weixin_63253486/article/details/131421022

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/4848.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MacPro(M1,M2芯片)Java开发和常用工具开源软件合集

目录 Java开发软件1 IDE1.1 idea1.2 Vs Code 2 开发工具2.1 数据库数据库模型管理数据库连接客户端 2.2 SSH/Telnet/Serial/Shell/Sftp客户端2.3 MarkDown编辑器2.3 代码片段管理粘贴 3小工具3.1 截图贴图3.2 Mac下修改hosts文件的图形化界面软件 Java开发软件 1 IDE 1.1 ide…

如果把软路由的网段更换成169.254.0.0/16会咋样?

前言 这几天有小伙伴在折腾软路由系统,然后问题就来了。 他咨询的是:为啥电脑连接软路由之后,无法访问软路由的管理页? 嗯。。。确实不是什么大事。但不注意看,还以为软路由没有正常获取到ip。 熟悉网络的小伙伴们都…

教程推荐:手机应用自动化

手机应用程序的自动化通常涉及使用专门设计的自动化框架和工具。对于Android和iOS平台,以下是一些常用的自动化工具: Android: Espresso: Espresso是谷歌官方支持的自动化测试框架。它适用于写UI测试来模拟用户对Android应用的交云。Espresso工作在应用…

Python中的map()和filter()函数:深入解析与使用场景

Python中的map()和filter()函数:深入解析与使用场景 在Python编程中,map()和filter()是两个非常实用的内置函数,它们可以帮助我们更高效地处理数据。这两个函数都是高阶函数,可以接受一个函数作为参数,并应用于序列&a…

实例解释:溢出和进位是咋回事?不能胡来吧!

有学生给我一段程序,就在运行中标志位的“怪异”表现提出问题。   程序不难懂: assume cs:codesg codesg segment start:mov al,0fchadd al,05h ;结果不溢出mov al,0f5hadd al,87h ;结果溢出mov ax,4c00hint 21h codesg ends end start难懂的是&a…

设计模式- 访问者模式(Visitor Pattern)结构|原理|优缺点|场景|示例

设计模式(分类) 设计模式(六大原则) 创建型(5种) 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式 结构型(7种) 适配器…

leetcode-有效括号序列-94

题目要求 思路 1.使用栈的先进后出的思路,存储前括号,如果st中有对应的后括号与之匹配就说明没问题 2.有两个特殊情况就是字符串第一个就是后括号,这个情况本身就是不匹配的,还有一种是前面的n个字符串本身是匹配的,这…

Python中format的常见用法

一、填充 1、按默认顺序填充 name "Alice" age 25 print("My name is {} and I am {} years old.".format(name, age))输出:My name is Alice and I am 25 years old. 2、指定位置 name "Bob" age 30 print("My name is…

与Apollo共创生态:我们携手远航

目录 小程一言会议记录 回望7年发展展望未来小程有感 小程一言 4月22日,百度Apollo在北京车展前夕举办了以“破晓•拥抱智变时刻”为主题的智能汽车产品发布会。我在观看后也是很是触动 作为在校大学生的我,从大一开始知道Apollo开始,Apollo…

2024.04.09 校招 实习 内推 面经

绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、校招&实习 | 佑驾创新Minieye 春招补录实习(内推) 校招&实习 | 佑驾创新Minieye 春招补录实习(内推) 2、校招 | 上海复旦微电子…

STM32中I2C通信的完整C语言代码范例

在嵌入式系统开发中,STM32芯片是一种广泛应用的微控制器,具有强大的性能和丰富的外设功能。其中,I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,用于在微控制器之间或者微控制器与外设之间进行数…

高并发实现高效内存管理

高并发下传统方式的弊端 void *malloc(size_t size);在内存的动态存储区中分配一块长度为size字节的连续区域返回该区域的首地址. void *calloc(size_t nmemb, size_t size);与malloc相似,参数size为申请地址的单位元素长度,nmemb为元素个数&#xff0…

开发中git的常用操作

Git 是一款分布式版本控制系统,广泛应用于软件开发中,用于管理项目的版本和修改历史。在开发过程中,有许多常用的 Git 操作可以帮助团队协作、版本管理和代码管理。下面将详细讲解常用的 Git 操作,并通过举例说明它们的用法和作用…

软考高级 | 系统架构设计师笔记(一)

一. 系统规划 1.1 项目的提出与选择 该步骤生成” 产品/项目建议书”. 1.2 可行性研究与效益分析 包括经济可行性/技术可行性/法律可行性/执行可行性/方案选择 5 个部分. 该步骤生 成”可行性研究报告”. 1.3 方案的制订和改进 包括确定软件架构/确定关键性要素?/确定计算…

spring-boot控制bean的创建顺序

1、order注解(不一定有效) org.springframework.core.annotation.Order 2、dependsOn注解(有效) org.springframework.context.annotation.DependsOn 3、提前将bean注册为BeanDefinition 1、实现BeanDefinitionRegistryPostP…

商城数据库88张表结构(八)

DDL 29.商品规格表 CREATE TABLE wang_goods_specs (id int(11) NOT NULL AUTO_INCREMENT COMMENT 自增ID,shopId int(11) NOT NULL DEFAULT 0 COMMENT 店铺ID,goodsid int(11) NOT NULL DEFAULT 0 COMMENT 商品ID,productNo varchar(20) NOT NULL COMMENT 商品货号,specids v…

Python 自定义日志输出

Python 有着内置的日志输出模块:logging 使用也很方便,但我们今天不说这个,我们用文件读写模块,实现自己的日志输出模块;这样在项目中,可以存在更高的自由度及更高的扩展性; 先来看看日志输出…

TDengine高可用架构之TDengine+Keepalived

之前在《TDengine高可用探讨》提到过,TDengine通过多副本和多节点能够保证数据库集群的高可用。单对于应用端来说,如果使用原生连接方式(taosc)还好,当一个节点下线,应用不会受到影响;但如果使用…

探索AI作画算法的原理:从深度学习到创造性艺术

引言 介绍AI在不同领域的应用,以及AI作画算法对于创造性艺术的影响。概述将在本文中讨论的主要内容。 第一部分:深度学习与计算机视觉 深度学习的基本原理:神经网络的结构和训练过程。计算机视觉的重要性:图像识别、生成和处理…

Python爬虫--Scrapy框架安装

Scrapy框架安装 , Scrapy 是 Python 领域专业的爬虫开发框架,已经完成爬虫程序的大部分通用工具 它使用了 Twisted 异步网络库来处理网络通讯。整体架构大致如下 第一步:挂小灰机或者将要安装的文件下载到本地 Scrapy 框架安装踩坑中 为什…