python 哔哩哔哩视频去水印

使用python 去除视频中的水印

1. 需要安装的包

pip install moviepy

pip install numpy

pip install opencv_python

pip install tqdm

2. 代码

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

# 判断输入是否为视频
def is_valid_video_file(file):
    try:
        with VideoFileClip(file) as video_clip:
            return True
    except Exception as e:
        print(f"Invalid video file: {file}, Error: {e}")
        return False

def get_first_valid_frame(video_clip, threshold=10, num_frames=10):
    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):
    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))
    print("r_original: ", r_original)
    return r_original
    #return (18, 28, 230, 43)
def detect_watermark_adaptive(frame, roi):
    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]] = 255 #binary_frame

    return mask

def generate_watermark_mask(video_clip, num_frames=10, min_frame_count=7):
    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):
    total_frames = int(video_clip.duration * video_clip.fps)
    progress_bar = tqdm(total=total_frames, desc="Processing Frames", unit="frames")
    #num=0
    def process_frame(frame):
        result = apply_mask_func(frame)
        progress_bar.update(1000)
        #global num
        #num += 1
        #result.save('0%5d.png' % num)
        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__":

    video = "1476212253-1-192.mp4"
    output_video_path = "output/1476212253-1-192.mp4"
    
    if is_valid_video_file(video):
        video_clip = VideoFileClip(video)
        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(video)
        process_video(video_clip, output_video_path, mask_func)
        print(f"Successfully processed {video_name}")

3. 运行

使用鼠标框选水印,回车继续。

开始处理

4. 完成后效果对比

去除前:

1476212253-1-192_o

去除后:

1476212253-1-192.mp4

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

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

相关文章

第九届全国大学生GIS应用技能大赛试题答案及数据下载(下午)

一、案例背景 我们现在是江苏省城市研究科研项目组的一员,我们分配到了以下任务: **任务一:**创建三甲医院 20 分钟、45 分钟服务区,并计算每一个地级市/县级市拥有的三甲医院 20 钟、45 分钟服务区占全市面积百分比。 **任务二&a…

ERROR: No matching distribution found for sklearn.cross_validation

问题 ERROR: Could not find a version that satisfies the requirement sklearn.cross_validation (from versions: none) ERROR: No matching distribution found for sklearn.cross_validation 错误:找不到满足sklearn要求的版本。Cross_validation (from versions: none)…

Nginx开发实战三:替换请求资源中的固定数据

文章目录 1.效果预览2.下载Nginx解压并初始化3.字符串替换模块安装4.修改nginx配置文件并重启 1.效果预览 页面初始效果 页面替换后效果 说明:页面是内网的一个地址,我们通过nginx可以很便捷的将其改为外网访问,但是在外网访问这个地址后&#xff0c…

算法之美:二叉堆原理剖析及堆应用案例讲解及实现

什么是堆 堆(Heap)是计算机科学中一类特殊的数据结构,通常是一个可以被看做一棵完全二叉树的数组对象。 完全二叉树 只有最下面两层节点的度可以小于2,并且最下层的叶节点集中在靠左连续的边界,只允许最后一层有空缺结点且空缺在右边&#x…

工艺品wordpress外贸主题

工艺品wordpress外贸主题 简约大气的wordpress外贸主题,适合做工艺品进出品外贸的公司官网使用。 https://www.jianzhanpress.com/?p5377

记一次 pdfplumber 内存泄漏导致的服务器宕机

有一个项目需求,要在每天凌晨5点的时候执行一个任务,获取一系列的PDF文件并解析。 后端是Django框架,定时任务用Celery来实现的。 本地跑没什么问题,但是一放到服务器上跑就会宕机,而且是毫无征兆的宕机,…

前端学习<二>CSS基础——17-CSS3的常见边框汇总

CSS3 常见边框汇总 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>CSS3 边框</title><style>body, ul, li, dl, dt, dd, h1, h2, h3, h4, h5 {margin: 0;padding: 0;}​body {background-c…

erp系统开发报价:企业如何选择一套合适的智能erp管理系统-亿发

在选择ERP系统时&#xff0c;企业通常希望了解上一套系统到底需要多少资金&#xff0c;但实际上这个问题并没有一个明确的答案。一般的erp系统从几万到几百万不等&#xff0c;一些简单的erp系统甚至只需要几千元。ERP系统的价格取决于多种因素&#xff0c;包括企业的业务规模、…

Linux多进程通信(1)——无名管道及有名管道使用例程

管道是半双工通信&#xff0c;如果需要 双向通信&#xff0c;则需要建立两个管道&#xff0c; 无名管道&#xff1a;只能父子进程间通信&#xff0c;且是非永久性管道通信结构&#xff0c;当它访问的进程全部终止时&#xff0c;管道也随之被撤销 有名管道&#xff1a;进程间不需…

【算法刷题day14】二叉树理论基础、递归遍历、迭代遍历、统一迭代

二叉树理论基础 题目分类 二叉树的种类 无数值两种&#xff1a;满二叉树 和 完全二叉树 有数值&#xff1a;二叉搜索树 1.若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值; 2.若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它的根结点…

Python快速入门系列-6(Python高级特性)

第六章: Python高级特性 6.1 列表推导式与生成器6.1.1 列表推导式6.1.2 生成器6.1.2.1 生成器表达式6.1.2.2 生成器函数6.2 装饰器与迭代器6.2.1 装饰器6.2.2 迭代器6.3 异常处理与错误调试6.3.1 异常处理6.3.1.1 try-except语句6.3.1.2 try-except-else语句6.3.2 错误调试6.3…

恶劣条件下GNSS定位的鲁棒统计

全球导航卫星系统&#xff08;GNSS&#xff09;作为定位信息的主要来源&#xff0c;在智慧工厂、智慧能源、智慧交通的未来应用中发挥着重要作用。此外&#xff0c;GNSS为电网或股市等关键应用提供定时同步功能。然而&#xff0c;GNSS的性能很容易因自然现象和信号反射而降低。…

AI技术创业有哪些机会?

AI技术创业有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随着AI技术的快速发展和应用领域的不断拓展&#xff0c;未来AI技术方面会有哪些创业机会呢&#xff1f; 创什么业打工才是…

Fluentd介绍

1.什么是Fluentd Fluentd是一个开源的日志收集和分发系统&#xff0c;它能够从多种数据源采集日志信息&#xff0c;并对日志进行过滤、加工处理后发送到不同的存储和处理系统。 以下是关于Fluentd的一些关键信息&#xff1a; 基本概念&#xff1a;Fluentd被设计为一个高性能…

RPA机器人如何支持滑块验证码?泽众RPA如何轻松解决?

为了提高软件的安全性&#xff0c;很多系统&#xff0c;包括web系统和手机上的应用&#xff0c;越来越多的使用验证码来提升系统的安全性&#xff0c;防止非法访问&#xff0c;特别是防止机器人的访问。 如上图所示&#xff0c;就是最近比较常用的“滑块验证码”。它要求用户“…

广告业务知识-数据

最近做了些广告业务&#xff0c;梳理下&#xff0c;分广告术语、业务架构、数据架构三篇。以效果广告为例&#xff0c;下面是数据篇&#xff08;图片做了脱敏处理哈&#xff09;&#xff1a; 1.效果广告实体关系 2.广告数据大图 2.1数据模块大图 2.2 详细核心数据大图

ollama本地部署大模型(纯CPU推理)实践

文章目录 说明Ollama和Ollama WebUI简介Ollama模型硬件要求内存要求 Ollama容器部署Ollama容器内模型下载和对话Ollama WebUI部署Ollama WebUI下载模型和对话轻量模型推荐机器硬件信息概览qwen:0.5b推理体验gemma:7b推理体验 说明 本文旨在分享在linux(centos8)平台使用docker…

ry - vue项目 docker部署

一、创建网络 1.搭建net-ry局域网 用于部署若依项目 docker network create net-ry --subnet172.68.0.0/16 --gateway172.68.0.1查看一下。 2、关闭防火墙 1&#xff09;、关闭防火墙 systemctl stop firewalld如果不关闭防火墙&#xff0c;容器内部的mysql、redis等服务…

“一起华裔洗钱案震惊全球”,涉案6.1万枚比特币!英国欲将其“充公”?中方:赃款为潜逃资金,有权追回!

最近&#xff0c;英国警方公布了一桩国际洗钱大案&#xff0c;查获超过6.1万枚比特币&#xff0c;这些资金由华裔英国女子Jian Wen&#xff08;温简&#xff09;涉嫌协助被中国通缉的诈骗集团首脑Zhimin Qian&#xff08;钱志敏&#xff09;而获得&#xff0c;据悉她将于5月10日…

正大国际:安全合规的外盘期货途径

“外盘期货”一词是指在中国大陆以外建立的期货交易市场。交易所基于国内期货和外盘期货的全球定价、价格权威、巨大的外部交易量、成熟的交易市场和交易机制、强大的流动性、巨大的市场容量、在中国大陆没有控制和强劲的趋势。然而&#xff0c;许多人被引诱进入非法甚至非法平…