python practical method of removing video watermarks and subtitles

1. How to remove video watermark using python

Get resource link:https://null119.lanzoul.com/b050jscbg

1. Download the resource package and unzip it

        The result is shown below:

2. Install the interpreter and packages necessary to run the code

        ​ ​ ​ Python software can be downloaded from the official website. Here we only introduce how to install packages in batches, as shown below

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

#-r后是需要安装的包的名称构成的txt文档
#-i后国内的镜像地址,下载会快一点

3. Put related videos into the video folder

        ​​​​Note: The resolution of the files must be the same and the watermark position must be the same, otherwise batch operations cannot be performed.

4.Startup script

        Open the command line, first enter python, press Enter, and then enter the script name to run the script.

 5. Select the command and then select the area to remove it.

 

 6. Find processed videos

        In the output video.

2. Actual overall code

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()

3. How to remove watermark from images

(1) Mobile phone - Lucky Love Watermark Wizard

        It’s a bit free to remove the watermark, you can invalidate the operation, but you can only save one per day. The good thing is that if you invite someone, you can get 60 save opportunities, and the invited person can also get ten times, and you can P-picture.

(2) Computer - quququ.cn

        Drag the picture to the website, adjust the size of the brush, erase the text to complete the P picture, and download it for free.

4. References

[1] Use Python to easily remove video watermarks/subtitles, step-by-step tutorial, learn it in one go_bilibili_bilibili

[2]https://ztjun.fun/ (Station B: Zhitingjun)

Guess you like

Origin blog.csdn.net/weixin_63253486/article/details/131421022