首页 > Python资料 博客日记

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

2024-07-13 00:00:04Python资料围观299

这篇文章介绍了【python】去除水印的几种方式,分享给大家做个参考,收藏Python资料网收获更多编程知识

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

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

import subprocess
 
def 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 np
 
def 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_loc
        bottom_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'):
            break
    else:
        break
 
cap.release()
out.release()
cv2.destroyAllWindows()

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

import os
import sys
import cv2
import numpy
from moviepy import editor
 
VIDEO_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.7
        w, 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) // 5
        index = 0
        while success:
            if index % step == 0:
                mask = cv2.bitwise_and(mask, self.generate_single_mask(frame, roi, self.threshold))
            success, frame = video.read()
            index += 1
        video.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 telea
 
 
    def 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.audio
            with 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 = None
 
        for 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


版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐