Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之十二 简单把视频的水印去掉效果

ops/2024/12/23 6:16:06/

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之十二 简单把视频的水印去掉效果

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之十二 简单把视频的水印去掉效果

一、简单介绍

二、简单把视频的水印去掉效果实现原理

三、简单把视频的水印去掉效果案例实现简单步骤

四、注意事项


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

这里使用 Python  基于 OpenCV 进行视觉图像处理,......

二、简单把视频的水印去掉效果实现原理

去除视频水印是指在视频中移除嵌入的标识、图标、文字或任何其他可视元素的过程。这些水印通常是为了保护知识产权、标识所有权或添加额外信息而添加到视频中的。去除水印可以提高视频的质量和观看体验,特别是当水印影响了视频的内容或美观性时。去除水印的方法通常包括使用图像处理技术,如图像修复、遮罩生成、内容填充等。

实现原理

  • 代码首先获取视频的第一个有效帧,用于选择水印的ROI(感兴趣区域)。
  • 然后用户可以通过交互式界面在视频中选择水印的ROI,以便后续处理。
  • 接着,通过自适应的方法检测水印并生成水印的遮罩。
  • 最后,利用生成的水印遮罩,对视频进行修复,去除水印

实现方法

  • get_first_valid_frame(video_clip, threshold=10, num_frames=10):获取视频的第一个有效帧,用于选择水印的ROI。它通过计算视频中多个帧的均值来确定第一个有效帧。
  • select_roi_for_mask(video_clip):通过交互式界面在视频中选择水印的ROI,返回水印的ROI坐标和尺寸。
  • detect_watermark_adaptive(frame, roi):自适应检测水印并生成水印的遮罩。它在水印的ROI上应用灰度化和二值化来检测水印。
  • generate_watermark_mask(video_clip, num_frames=10, min_frame_count=7):生成水印的遮罩。它在视频的多个帧中检测水印,并根据水印像素点在至少指定数量的帧中出现的次数来生成最终的水印遮罩。
  • process_video(video_clip, output_path, apply_mask_func):处理视频并保存结果。它将给定的应用遮罩函数应用于视频的每一帧,并将处理后的视频保存到指定路径。

涉及的关键函数及其说明:

  1. get_first_valid_frame(video_clip, threshold=10, num_frames=10)

    • 功能:获取视频的第一个有效帧,用于选择水印的ROI。
    • 参数:
      • video_clip:视频剪辑对象。
      • threshold:判断帧是否有效的阈值,默认为10。
      • num_frames:用于选择的帧的数量,默认为10。
    • 返回值:第一个有效帧的图像数据。
  2. select_roi_for_mask(video_clip)

    • 功能:从视频剪辑中选择水印的ROI。
    • 参数:
      • video_clip:视频剪辑对象。
    • 返回值:水印ROI的坐标和尺寸 (x, y, w, h)。
  3. detect_watermark_adaptive(frame, roi)

    • 功能:自适应检测水印并生成遮罩。
    • 参数:
      • frame:视频帧的图像数据。
      • roi:水印的ROI坐标和尺寸 (x, y, w, h)。
    • 返回值:水印的遮罩图像数据。
  4. generate_watermark_mask(video_clip, num_frames=10, min_frame_count=7)

    • 功能:生成水印的遮罩。
    • 参数:
      • video_clip:视频剪辑对象。
      • num_frames:用于生成遮罩的帧的数量,默认为10。
      • min_frame_count:水印像素点在至少多少帧中出现才被认为是水印,默认为7。
    • 返回值:水印的遮罩图像数据。
  5. process_video(video_clip, output_path, apply_mask_func)

    • 功能:处理视频并保存结果。
    • 参数:
      • video_clip:视频剪辑对象。
      • output_path:输出视频路径。
      • apply_mask_func:应用遮罩的函数。
    • 返回值:无。

三、简单把视频的水印去掉效果案例实现简单步骤

1、编写代码

2、运行效果

操作:1、选择水印区域,2、然后空格或者回车,后台开始去除视频水印

3、具体代码

python">"""
简单的框选水印位置,移除水印1、代码首先获取视频的第一个有效帧,用于选择水印的ROI(感兴趣区域)。2、然后用户可以通过交互式界面在视频中选择水印的ROI,以便后续处理。3、接着,通过自适应的方法检测水印并生成水印的遮罩。4、最后,利用生成的水印遮罩,对视频进行修复,去除水印。
"""import cv2
import numpy as np
from moviepy.editor import VideoFileClip
import os
from tqdm import tqdmdef get_first_valid_frame(video_clip, threshold=10, num_frames=10):"""获取视频的第一个有效帧,用于选择水印的ROI:param video_clip: 视频剪辑对象:param threshold: 判断帧是否有效的阈值:param num_frames: 用于选择的帧的数量:return: 第一个有效帧的图像数据"""total_frames = int(video_clip.fps * video_clip.duration)frame_indices = [int(i * total_frames / num_frames) for i in range(num_frames)]for idx in frame_indices:frame = video_clip.get_frame(idx / video_clip.fps)if frame.mean() > threshold:return frame# 注意:不一定第一帧就有水印return video_clip.get_frame(0)def select_roi_for_mask(video_clip):"""从视频剪辑中选择水印的ROI:param video_clip: 视频剪辑对象:return: 水印ROI的坐标和尺寸 (x, y, w, h)"""frame = get_first_valid_frame(video_clip)# 将视频帧调整为720p显示display_height = 720scale_factor = display_height / frame.shape[0]display_width = int(frame.shape[1] * scale_factor)display_frame = cv2.resize(frame, (display_width, display_height))instructions = "Select ROI and press SPACE or ENTER"font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(display_frame, instructions, (10, 30), font, 1, (255, 255, 255), 2, cv2.LINE_AA)r = cv2.selectROI(display_frame)cv2.destroyAllWindows()r_original = (int(r[0] / scale_factor), int(r[1] / scale_factor), int(r[2] / scale_factor), int(r[3] / scale_factor))return r_originaldef detect_watermark_adaptive(frame, roi):"""自适应检测水印并生成遮罩。:param frame: 视频帧的图像数据:param roi: 水印的ROI坐标和尺寸 (x, y, w, h)。:return: 水印的遮罩图像数据。"""roi_frame = frame[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]]gray_frame = cv2.cvtColor(roi_frame, cv2.COLOR_BGR2GRAY)_, binary_frame = cv2.threshold(gray_frame, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)mask = np.zeros_like(frame[:, :, 0], dtype=np.uint8)mask[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]] = binary_framereturn maskdef generate_watermark_mask(video_clip, num_frames=10, min_frame_count=7):"""生成水印的遮罩:param video_clip: 视频剪辑对象:param num_frames: 用于生成遮罩的帧的数量:param min_frame_count: 水印像素点在至少多少帧中出现才被认为是水印:return: 水印的遮罩图像数据"""total_frames = int(video_clip.duration * video_clip.fps)frame_indices = [int(i * total_frames / num_frames) for i in range(num_frames)]frames = [video_clip.get_frame(idx / video_clip.fps) for idx in frame_indices]r_original = select_roi_for_mask(video_clip)masks = [detect_watermark_adaptive(frame, r_original) for frame in frames]final_mask = sum((mask == 255).astype(np.uint8) for mask in masks)# 根据像素点在至少min_frame_count张以上的帧中的出现来生成最终的遮罩final_mask = np.where(final_mask >= min_frame_count, 255, 0).astype(np.uint8)kernel = np.ones((5, 5), np.uint8)return cv2.dilate(final_mask, kernel)def process_video(video_clip, output_path, apply_mask_func):"""处理视频并保存结果:param video_clip: 视频剪辑对象:param output_path: 输出视频路径:param apply_mask_func: 应用遮罩的函数:return:"""total_frames = int(video_clip.duration * video_clip.fps)progress_bar = tqdm(total=total_frames, desc="Processing Frames", unit="frames")def process_frame(frame):result = apply_mask_func(frame)progress_bar.update(1000)return resultprocessed_video = video_clip.fl_image(process_frame, apply_to=["each"])processed_video.write_videofile(f"{output_path}.mp4", codec="libx264")if __name__ == "__main__":input_video_path = "Videos/CatRun_Wartermark.mp4"output_video_path = "Videos/CatRun_Wartermark_ToRemove.mp4"watermark_mask = Nonevideo_clip = VideoFileClip(input_video_path)if watermark_mask is None:watermark_mask = generate_watermark_mask(video_clip)mask_func = lambda frame: cv2.inpaint(frame, watermark_mask, 3, cv2.INPAINT_NS)video_name = os.path.basename(input_video_path)process_video(video_clip, output_video_path, mask_func)print(f"Successfully processed {video_name}")

四、注意事项

  1. 代码中使用了交互式界面让用户选择水印的ROI,因此运行代码时需要有图形界面的支持。
  2. 自适应检测水印的方法在一定程度上能够应对不同类型的水印,但并不是万能的,可能会存在一定的误差。
  3. 在检测水印时,需要根据实际情况调整参数,以获得最佳的检测效果。
  4. 去除水印时,采用了基于遮罩的修复方法,可能会对图像的质量产生一定的影响,需要根据实际需求权衡。

http://www.ppmy.cn/ops/2604.html

相关文章

Debian

文章目录 前言一、使用root用户操作二、配置用户使用sudo命令三、添加桌面图标显示1.打开终端2.执行安装命令3.执行成功后重启4. 打开扩展,配置图标 四、图形化界面关闭和打开五、设置静态IP1.查询自己系统网络接口2.修改网络配置文件 总结 前言 Debian 系统在安装…

利用正射影像对斜射图像进行反向投影

在图像投影和映射领域,有两种类型的投影:正向投影和反向投影。正向投影涉及使用内部方向(即校准相机参数)将 3D 点(例如地面上的物体)投影到 2D 图像平面上。另一方面,向后投影是指根据 2D 图像确定地面物体的 3D 坐标的过程。 为了匹配倾斜图像和正射影像并确定相机位置…

意大利侍酒师Galvan Maurizia分享意大利葡萄酒与美食文化魅力

在酒水行业日益繁荣的今天,消费者对酒类产品的品质、文化和品味的追求不断提升。为了满足这一市场需求,云仓酒庄近日宣布开启首届《综合品酒师》培训,旨在培养更多具备专业素养和品鉴能力的品酒师,为酒水行业的专业化和形象提升注…

浅谈mybatis

说说mybaits原理 首先,之前Java连接数据库jdk有定义一套规范JDBC,但是这个规范使用起来太麻烦, 流程大概有加载驱动、连接数据库、执行sql、处理结果、释放资源。 特别是sql是以字符串的形式进行传参的, 所以在写sql时需要在代码…

【opencv】示例-phase_corr.cpp 捕获视频流并通过计算相位相关性来检测画面中的移动...

// 包含OpenCV库的头文件 #include "opencv2/core.hpp" // 包含OpenCV核心功能 #include "opencv2/videoio.hpp" // 包含视频IO功能 #include "opencv2/highgui.hpp" // 包含高级GUI功能,显示图像 #include "opencv2/imgproc.hp…

【Java实战】使用自定义注解实现参数校验详解

文章目录 前言📝一、Java注解简介二、启用注解校验1.启用注解2.注解@Valid和 @Validated2.1@Valid级联校验2.2@Validated高级使用三、自定义注解1.统一异常处理2.编写注解2.1 自定义校验2.2 多参数校验总结前言📝 由于实际开发中遇到大量相同的条件参数验证,不想写重复代…

天空盒1-天空盒的实现原理

天空盒是一种常用的实时渲染技术,用于在三维场景中模拟远处环境,例如天空、山脉或城市等。它通过将一个立方体贴图(也称为环境贴图)投影到场景的背景中,给人一种无限远的感觉。以下是天空盒的实现原理: 创建…

git中checkout的用法总结

切换分支 # 切换分支,如果有本地分支,则表示切换到该分支上; # 如果是远端仓库分支,表示把远端仓库分支下载到本地仓库中 git checkout 分支名# 创建一个分支,并进行切换 git checkout -b 分支名撤销对文件的修改 # …