MP4如何让去水印?python带你实现~

您所在的位置:网站首页 mp4文件怎么去字幕水印 MP4如何让去水印?python带你实现~

MP4如何让去水印?python带你实现~

2024-07-14 13:10| 来源: 网络整理| 查看: 265

前言

嗨喽,大家好呀~这里是爱看美女的茜茜呐

开发环境:

解释器版本: python 3.8

代码编辑器: pycharm 2021.2

模块使用:

内置模块(无需安装)

os —> python系统编程的操作模块,提供了非常丰富的功能去处理文件和目录

sys —> 是与Python解释器交互的桥梁

cv2 —> 流行的开源计算机视觉库,提供了丰富的图像和视频处理功能

第三方模块

numpy —> 用于数值计算的基础模块,支持大量的维度数值与矩阵计算

moviepy —> 用于视频剪辑、合成和处理

第三方模块安装:

win + R 输入 cmd 点击确定, 输入安装命令 pip install 模块名 (pip install requests) 回车

在pycharm中点击Terminal(终端) 输入安装命令

模块可能安装失败原因:出现大量报红 (read time out)

解决方法: 因为是网络链接超时, 需要切换镜像源

可使用镜像源例举:

清华:https://pypi.tuna.tsinghua.edu.cn/simple

中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/

华中理工大学:https://pypi.hustunique.com/

山东理工大学:https://pypi.sdutlinux.org/

例如:pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple/ 模块名

👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~

素材、视频教程、完整代码、插件安装教程我都准备好了,直接在文末名片自取就可

代码展示

导入模块

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 # 膨胀运算核尺寸 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 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) 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() 尾语

感谢你观看我的文章呐~本次航班到这里就结束啦 🛬

希望本篇文章有对你带来帮助 🎉,有学习到一点知识~

躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。

最后,宣传一下呀~👇👇👇更多源码、资料、素材、解答、交流皆点击下方名片获取呀👇👇



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3