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

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、具体代码

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

import cv2
import numpy as np
from moviepy.editor import VideoFileClip
import os
from tqdm import tqdm


def 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 = 720
    scale_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_SIMPLEX
    cv2.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_original


def 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_frame

    return mask


def 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 result

    processed_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 = None

    video_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. 在去除水印时,采用了基于遮罩的修复方法,可能会对图像的质量产生一定的影响,需要根据实际需求权衡。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MVVM架构模式

目录 MVVM 数据绑定方式 实现方式 Model View ViewModel 数据绑定方式 vue:: 数据劫持和发布-订阅模式: Object.defineProperty() 方法来劫持(监控)各属性的 getter 、setter ,并在数据(对…

centos7上安装python3.10

1 安装依赖 使用yum程序安装所需依赖。打开终端并运行以下命令: yum install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make zlib zlib-devel libffi-devel -y 这些依赖项是编译和安装Python 3.10所必…

结合文本的目标检测:Open-GroundingDino训练自己的数据集

1、简单介绍 Open-GroundingDino是GroundingDino的第三方实现训练流程的代码,因为官方GroundingDino没有提供训练代码,只提供了demo推理代码。 关于GroundingDino的介绍可以看论文:https://arxiv.org/pdf/2303.05499.pdf GroundingDino的G…

没有算法大佬,都是草台班子

没有算法大佬,都是草台班子。 最近除了工作之外,还有一些时间在和加我微信的小伙伴沟通,聊的内容大部分集中在如何快速有效的学习人工智能、入门人工智能的技巧。 其中,一个知乎过来加我微信的小伙伴的经历更是让我感触很深。 …

openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint

文章目录 openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint261.1 功能描述261.2 语法格式261.3 示例261.3.1 忽略非空约束261.3.2 忽略唯一约束261.3.3 忽略分区表无法匹配到合法分区261.3.4 更新/插入值向目标列类型转换失败 o…

AI 编程助手汇总

文章目录 AI编程助手~~GitHub学生认证申请(无效,申请不了了)~~GitHub双重身份验证 AI编程助手 Baidu Comate (强推✔) 阿里通义灵码 清华CodeGeeX Amazon CodeWhisperer (需要注册账号,绑定信…

秋招算法刷题7

20240410 1.接雨水 方法一,动态规划,时间复杂度O(n^2),空间复杂度O(n) public int trap(int[] height) { int nheight.length; if(n0){ return 0; } …

python 海龟画图tutle螺旋线

目录 初识turtle模块 基本绘图概念 示例:绘制一个正方形 示例:绘制彩色螺旋线 附录 常用命令 其它命令 在Python编程中,使用turtle模块进行图形绘制是一种非常有趣和富有教育意义的活动。通过控制一个小海龟(Turtle&#x…

RabbitMQ消息模型之Direct消息模型

Direct消息模型 * 路由模型: * 一个交换机可以绑定多个队列 * 生产者给交换机发送消息时,需要指定消息的路由键 * 消费者绑定队列到交换机时,需要指定所需要消费的信息的路由键 * 交换机会根据消息的路由键将消息转发到对应的队…

ModuleNotFoundError: No module named ‘llama_index.readers“解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

“We Need Structured Output”: 以用户为中心的大模型输出

发表机构:Google Research 这篇论文的核心是设计了一种系统,可以让开发者和用户对大型语言模型的输出施加结构性约束。系统的主要部分包括: 1. 用户界面(GUI):允许用户通过图形界面来定义他们希望LLM遵守…

Redis中的BigKey

Redis中的BigKey 文章目录 Redis中的BigKey什么是BigKey?BigKey的危害找到Bigkey删除BigKey优化BigKeyBigKey对持久化的影响对AOF日志的影响对AOF重写和RDB的影响 什么是BigKey? 大 key 并不是指 key 的值很大,而是 key 对应的 value 很大。…

最新版IntelliJ IDEA 2024.1安装和配置教程 详细图文解说版安装教程

IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版 文章目录 IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版前言 第一步: IntelliJ IDEA 2024.1安装教程第 0 步&…

python数据结构与算法之线性表

1、线性表 是一种由n个元素(n> 0 )数据元素组成的有限序列,所包含的元素数量通常被称为表的长度 n 0 的表被称为空表,线性表的数据元素可以单一也可以复杂,可以是整数,字符串,也可以是由几…

H.265视频直播点播录像EasyPlayer.js流媒体播放器用户常见问题及解答

EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,无须安装任何插件,起播快、延迟低、兼容性强,使用非常便捷。 今天我们来汇总下用户常见的几个问题及解答。 1、EasyPlayer.js播放多路H.265视…

HCIP的学习(9)

OSPF的接口网络类型 ​ OSPF的接口在某种网络类型下的工作方式。 网络类型OSPF接口的工作方式BMABroadcast;可以建立多个邻居关系。需要进行DR选举。hello 10S;dead 40S。P2PP2P;只能建立一个邻居关系,不需要进行DR选举。Hello …

【个人博客搭建】(3)添加SqlSugar ORM

1、安装sqlsugar。在models下的依赖项那右击选择管理Nuget程序包,输入sqlsugarcore(因为我们用的是netcore,而不是net famework所以也对应sqlsugarcore),出来的第一个就是了,然后点击选择版本,一…

三斜求积术 To 海伦公式 ← 三角形面积

【知识点:三斜求积术】 所谓秦九韶的三斜求积术,即如果已知三角形的边长a,b,c,可求得该三角形的面积为: 而由三斜求积术可推得海伦公式。过程如下: 其中, 上面推导公式的 Latex 代码…

《QT实用小工具·二十六》运行时间记录

1、概述 源码放在文章末尾 运行时间记录,包含如下功能: 可以启动和停止服务,在需要的时候启动。 可以指定日志文件存放目录。 可以指定时间日志输出间隔。 可以单独追加一条记录到日志文件。 日志为文本格式,清晰明了。 软…

记一次生产环境Java堆内存溢出问题排查思路

文章目录 1. 用Visual VM 加载堆转储文件2. 用Visual VM 分析堆转储文件3. 结合分析结果,定位并解决问题 1. 用Visual VM 加载堆转储文件 先将转储文件从服务器下载下来,打开Visual VM,点击右上角的Load Snapshot,将这个转储文件加载到Visua…