Python 视频转场特效处理笔记

本文参考Python-OpenCV 实现美图秀秀视频剪辑效果【特效】_opencv 多张图片 视频 特效-CSDN博客

最近研究了点python处理视频相关的东西,本文展示特效包括,竖向开幕/横向开幕,渐隐/渐显,推近/拉远,方形开幕,灰度渐变。不多说,直接上代码。

import cv2
import numpy as np
import random

def addCardFrame(video_writer,img,backimg=None,fps=18,sec=1,eachtime=0.5):
    """视频特效:卡帧"""
    rows, cols = img.shape[:2]

    '''缩放原图80%'''
    img = cv2.resize(img, (int(cols * 0.8),int(rows * 0.8)))
    rows_new, cols_new = img.shape[:2]

    '''准备更大的画布'''
    cav = None
    if backimg is None:
        cav_np = np.zeros((rows, cols), np.uint8)
        cav = cv2.cvtColor(cav_np, cv2.COLOR_GRAY2BGR)
    else:
        cav = backimg

    '''偏移量准备'''
    dic = {
        0: (int(cols * 0.08), int(rows * 0.12)),
        1: (int(cols * 0.10), int(rows * 0.10)),
        2: (int(cols * 0.12), int(rows * 0.08)),
        3: (int(cols * 0.12), int(rows * 0.07)),
        4: (int(cols * 0.12), int(rows * 0.06)),
        5: (int(cols * 0.14), int(rows * 0.07)),
        6: (int(cols * 0.16), int(rows * 0.07)),
        7: (int(cols * 0.15), int(rows * 0.09)),
        8: (int(cols * 0.14), int(rows * 0.10)),
        9: (int(cols * 0.14), int(rows * 0.07)),
        10: (int(cols * 0.13), int(rows * 0.05)),
        11: (int(cols * 0.14), int(rows * 0.06)),
        12: (int(cols * 0.14), int(rows * 0.08)),
        13: (int(cols * 0.15), int(rows * 0.10)),
        14: (int(cols * 0.14), int(rows * 0.09)),
        15: (int(cols * 0.12), int(rows * 0.12)),
        16: (int(cols * 0.10), int(rows * 0.10)),
        17: (int(cols * 0.08), int(rows * 0.12))
    }

    '''添加特效展示'''
    for _ in range(int(sec)):
        xs, ys = dic[random.randrange(0,18,1)]
        xe, ye = (xs + rows_new, ys + cols_new)
        cav[xs: xe, ys: ye] = img
        for _ in range(int(eachtime*fps)):
            video_writer.write(cav)

def addVerticalOpening(video_writer,img,backimg=None,fps=18,sec=1,mode='H'):
    """视频特效:竖向开幕H 横向开幕V"""
    rows, cols = img.shape[:2]

    '''画布准备'''
    cav = None
    if backimg is None:
        cav_np = np.zeros((rows, cols), np.uint8)
        cav = cv2.cvtColor(cav_np, cv2.COLOR_GRAY2BGR)
    else:
        cav = backimg

    '''特效展示'''
    load_f = 1000/fps
    n = 5
    height_half,weight_half = int(rows / 2),int(cols / 2)
    xs1, xs2 = height_half, height_half
    xe1, xe2 = height_half, height_half
    ys1, ys2 = weight_half, weight_half
    ye1, ye2 = weight_half, weight_half
    for t in range(int(sec*1000 // load_f)):
        load_percent = 0.5 / (sec ** n) * ((sec - t * load_f / 1000) ** n)
        if mode=='H':
            load_height = int((0.5 - load_percent) * rows)
            xe1, xe2 = height_half - load_height, height_half + load_height
            cav[xe1:xs1, :] = img[xe1:xs1, :]
            cav[xs2:xe2, :] = img[xs2:xe2, :]
            xs1, xs2 = xe1, xe2
        else:
            load_weight = int((0.5 - load_percent) * cols)
            ye1, ye2 = weight_half - load_weight,weight_half + load_weight
            cav[:, ye1:ys1] = img[:, ye1:ys1]
            cav[:, ys2:ye2] = img[:, ys2:ye2]
            ys1, ys2 = ye1, ye2
        video_writer.write(cav)

def addFadeOut(video_writer,img,backimg=None,fps=18,sec=2):
    """视频特效:渐隐"""

    '''特效展示'''
    load_f = 1000/fps
    n = 1
    for t in range(int(sec * 1000 // load_f)):
        sc = 1 - 1 / (sec ** n) * (t * load_f / 1000) ** n
        img_show = cv2.multiply(img, (1, 1, 1, 1), scale=sc)
        video_writer.write(img_show)

def addFadeIn(video_writer,img,fps=18,sec=2):
    """视频特效:渐隐"""

    '''特效展示'''
    load_f = 1000/fps
    n = 1.5
    for t in range(int(sec * 1000 // load_f)):
        sc = 1 - 1 / (sec ** n) * (t * load_f / 1000) ** n
        sc = 1 - 1 / (sec ** n) * (sec - t * load_f / 1000) ** n
        img_show = cv2.multiply(img, (1, 1, 1, 1), scale=sc)
        video_writer.write(img_show)

def percent_func_gen(a, b, time, n, mode):
    """
    高次多项式计算函数生成器
    :param a: 起始百分比(如:0.25)
    :param b: 结束百分比
    :param time: 动画持续时间
    :param n: 多项式次数
    :param mode: faster(越来越快)、slower(越来越慢)
    :return: 每个时刻到达百分比的计算函数
    """
    if mode == "slower":
        a, b = b, a
    delta = abs(a - b)
    sgn = 1 if b - a > 0 else (-1 if b - a < 0 else 0)
    def percent_calc(ti):
        if mode == "slower":
            ti = time - ti
        return sgn * delta / (time ** n) * (ti ** n) + a
    return percent_calc
    
def addAdvance(video_writer,img,fps=18,sec=2):
    """视频特效:推近"""
    rows, cols = img.shape[:2]

    '''特效展示'''
    load_f = 1000/fps
    percent_func = percent_func_gen(a=0, b=0.2, time=sec, n=4, mode="slower")
    for t in range(int(sec * 1000 // load_f + 1)):
        percent = percent_func(t * load_f / 1000)
        xs, xe = int(percent * rows), int((1 - percent) * rows)
        ys, ye = int(percent * cols), int((1 - percent) * cols)
        img_show = img[xs:xe, ys:ye]
        img_show = cv2.resize(img_show, (cols,rows))
        video_writer.write(img_show)

def addZoomOut(video_writer,img,fps=18,sec=2):
    """视频特效:拉远"""
    rows, cols = img.shape[:2]

    '''特效展示'''
    load_f = 1000/fps
    percent_func = percent_func_gen(a=0.2, b=0, time=sec, n=3, mode="slower")
    for t in range(int(sec * 1000 // load_f + 1)):
        percent = percent_func(t * load_f / 1000)
        xs, xe = int(percent * rows), int((1 - percent) * rows)
        ys, ye = int(percent * cols), int((1 - percent) * cols)
        img_show = img[xs:xe, ys:ye]
        img_show = cv2.resize(img_show, (cols,rows))
        video_writer.write(img_show)

def addSquareOpening(video_writer,img,backimg=None,fps=18,sec=2):
    """视频特效:方形开幕"""
    rows, cols = img.shape[:2]
    '''画布准备'''
    cav = None
    if backimg is None:
        cav_np = np.zeros((rows, cols), np.uint8)
        cav = cv2.cvtColor(cav_np, cv2.COLOR_GRAY2BGR)
    else:
        cav = backimg
        
    '''特效展示'''
    load_f = 1000/fps
    percent_func = percent_func_gen(a=0, b=0.5, time=sec, n=5, mode="faster")
    rows_half = rows // 2
    cols_half = cols // 2
    for t in range(int(sec * 1000 // load_f + 1)):
        percent = percent_func(t * load_f / 1000)
        width, height = int(percent * rows), int(percent * cols)
        xs, xe = rows_half-width, rows_half+width
        ys, ye = cols_half-height, cols_half+height
        cav[xs:xe, ys:ye] = img[xs:xe, ys:ye]
        video_writer.write(cav)
        
def addGradientWipe(video_writer,img,backimg=None,fps=18,sec=2,mode='L'):   
    """视频特效:灰度渐变 L左 R右 U上 D下"""
    rows, cols = img.shape[:2]

    '''灰度准备'''
    img_gray_bgr = None
    if backimg is None:
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img_gray_bgr = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
    else:
        img_gray_bgr = backimg

    '''特效展示'''
    load_f = 1000/fps
    percent_func = percent_func_gen(a=0, b=1, time=sec, n=1, mode="slower")
    if mode=='L':
        ys, ye = 0, 0
        for t in range(int(sec * 1000 // load_f + 1)):
            percent = percent_func(t * load_f / 1000)
            width = int(percent * cols)
            ye = width
            img_gray_bgr[:, ys:ye] = img[:, ys:ye] 
            ys = ye
            video_writer.write(img_gray_bgr)
    if mode=='R':
        ys, ye = cols, cols
        for t in range(int(sec * 1000 // load_f + 1)):
            percent = percent_func(t * load_f / 1000)
            width = int(percent * cols)
            ys = cols-width
            img_gray_bgr[:, ys:ye] = img[:, ys:ye] 
            ye = ys
            video_writer.write(img_gray_bgr)
    if mode=='U':
        xs, xe = 0, 0
        for t in range(int(sec * 1000 // load_f + 1)):
            percent = percent_func(t * load_f / 1000)
            height = int(percent * rows)
            xe = height
            img_gray_bgr[xs:xe, :] = img[xs:xe, :] 
            xs = xe
            video_writer.write(img_gray_bgr)
    if mode=='D':
        xs, xe = rows, rows
        for t in range(int(sec * 1000 // load_f + 1)):
            percent = percent_func(t * load_f / 1000)
            height = int(percent * rows)
            xs = cols-height
            img_gray_bgr[xs:xe, :] = img[xs:xe, :] 
            xe = xs
            video_writer.write(img_gray_bgr)

调用方法进行视频合成

fps = 25 #视频帧数
sec = 3 # 特效时间
eachtime = 0.5 # 每帧所占时间
video_temp_path= "test.mp4"
img1 = cv2.imread("0.jpg")
img2 = cv2.imread("1.jpg")
img3 = cv2.imread("2.jpg")
video_height,video_weight =img.shape[:2]
video_writer = cv2.VideoWriter(video_temp_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (video_weight,video_height))
addCardFrame(video_writer,img1,fps,sec,eachtime)
addVerticalOpening(video_writer,img2,img1,fps,sec,mode='V')
addFadeOut(video_writer,img3,fps,sec)
addFadeIn(video_writer,img1,fps,sec)
addAdvance(video_writer,img2,fps,sec)
addZoomOut(video_writer,img3,fps,sec)
addSquareOpening(video_writer,img2,img3,fps,sec)
addGradientWipe(video_writer,img1,img2,fps,sec,mode='D')
video_writer.release()

视频效果如下:

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

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

相关文章

降准是什么意思?降准对股市有哪些影响?

降准是什么意思 降准&#xff0c;全称为“中央银行调低法定存款准备率”&#xff0c;是指中央银行降低法定存款准备率&#xff0c;以增加银行的可用资金&#xff0c;从而增加市场的流动性。 具体来说&#xff0c;存款准备金是商业银行为了应对储户取款和清算时准备的资金&…

Java集合框架(包装类、泛型)

前言&#xff1a; 本篇文章我们来讲解Java中的集合框架&#xff0c;就相当于车轮子。Java是面向对象的语言&#xff0c;所以相对于C语言有自身优势&#xff0c;就比如现成的数据结构&#xff08;比如栈&#xff0c;队列&#xff0c;堆等&#xff09;。Java的集合框架大家也不用…

猫头虎分享已解决Bug || 响应式布局错误(Responsive Design Issues):在移动设备上元素重叠、布局错位

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【stm32】hal库学习笔记-ADC模数转换(超详细)

【stm32】hal库学习笔记-ADC模数转换&#xff08;超详细&#xff09; 本篇章介绍了ADC实现电压检测的三种方式 ADC原理及选型 ADC将连续的模拟电压信号转换为二进制的数字信号 选型参数 速度&#xff08;采样频率&#xff09; 功耗 精度 转换原理 ADC hal库驱动函数 普通…

架构之模板方法等模式的使用

目录 一、程序编写背景 二、编程思路讲解 - 类图 - 实现逻辑 - 工厂模式 - 模板方法模式 接口类&#xff08;代码&#xff09;抽象类&#xff08;代码&#xff09;具体实现类&#xff08;代码&#xff09;工厂类&#xff08;代码&#xff09;注册类&#xff08;代码&…

安全之护网(HVV)、红蓝对抗

文章目录 红蓝对抗什么是护网行动&#xff1f;护网分类护网的时间 什么是红蓝对抗红蓝对抗演练的目的什么是企业红蓝对抗红蓝对抗价值参考 红蓝对抗 什么是护网行动&#xff1f; 护网的定义是以国家组织组织事业单位、国企单位、名企单位等开展攻防两方的网络安全演习。进攻方…

猫头虎分享已解决Bug || 内存溢出(Memory Overflow):OutOfMemoryError, MemoryLimitExceeded

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【前沿技术杂谈:多模态文档基础模型】使用多模态文档基础模型彻底改变文档 AI

【前沿技术杂谈&#xff1a;多模态文档基础模型】使用多模态文档基础模型彻底改变文档 AI 从文本到多模态模型&#xff1a;文档 AI 逐渐发展新技能。行业领先的型号Document AI 的下一步&#xff1a;开发通用和统一框架 您是否曾经被包含不同信息&#xff08;如应付账款、日期、…

成为CSDN博客优质创作者或者博客专家吧

成为CSDN博客优质创作者或者博客专家吧 文章目录 成为CSDN博客优质创作者或者博客专家吧一、前言二、如何成为CSDN的博客专家1、2009年的要求和申请方式2、最新的CSDN博客专家要求和申请方式3、创作者身份认证4、CSDN所有认证的介绍 三、写博客的好处1、比较官方的说法&#xf…

Redis 持久化对性能有何影响?

Redis 持久化对性能的影响 Redis 是一个高性能的内存数据存储系统&#xff0c;通常被用于缓存、消息队列和数据存储等方面。由于 Redis 是基于内存的&#xff0c;因此它的读写速度非常快&#xff0c;可以满足高并发、低延迟的应用需求。但是&#xff0c;当 Redis 需要持久化数…

Python实现文本情感分析

前言 文本情感分析是一种重要的自然语言处理(NLP)任务&#xff0c;旨在从文本数据中推断出情感信息&#xff0c;例如正面、负面或中性情感。它在社交媒体分析、产品评论、市场调研等领域都有广泛的应用。本文将详细介绍如何使用Python进行文本情感分析&#xff0c;包括基础概念…

公众号取关粉丝获取方法2

一、前言 之前和大家讲到了一篇关于这方面的文章&#xff0c;如下&#xff1a; 重要&#xff1a;获取公众号取关粉丝信息方法&#xff0c;全网只此一份 这种方法虽然挺好&#xff0c;不过也有一个弊端&#xff0c;那就是很多自作聪明的人如果隔一段时间再取关的话&#xff0…

公众号天气推送源码,附带教学,自动版本推送带各种模板

公众号天气推送系统介绍 主要功能特点&#xff1a; 实时天气查询&#xff1a;用户可以通过公众号随时查询当前位置的实时天气状况&#xff0c;包括温度、湿度、风速、天气状况等详细信息。定时推送服务&#xff1a;系统支持自定义时间段的天气推送&#xff0c;确保用户在出门…

NBA2K24 陈盈骏面补

NBA2K23-24 陈盈骏面补 NBA2K23-NBA2K24通用 陈盈骏面补 现效力于中国男子篮球职业联赛CBA广州龙狮 下载地址&#xff1a; https://www.changyouzuhao.cn/9617.html

手把手教你开发Python桌面应用-PyQt6图书管理系统-图书添加模块UI设计实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…

react将选中文本自动滑动到容器可视区域内

// 自动滚动到可视区域内useEffect(() > {const target ref;const wrapper wrapperRef?.current;if (target && wrapperRef) {const rect target.getBoundingClientRect();const wrapperRect wrapper.getBoundingClientRect();const isVisible rect.bottom &l…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Slider组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Slider组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Slider组件 滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调…

Camunda如何发送邮件及委托代码讲解

&#x1f496;专栏简介 ✔️本专栏将从Camunda(卡蒙达) 7中的关键概念到实现中国式工作流相关功能。 ✔️文章中只包含演示核心代码及测试数据&#xff0c;完整代码可查看作者的开源项目snail-camunda ✔️请给snail-camunda 点颗星吧&#x1f618; &#x1f496;什么是委托…

MATLAB实现LSTM时间序列预测

LSTM模型可以在一定程度上学习和预测非平稳的时间序列,其具有强大的记忆和非线性建模能力,可以捕捉到时间序列中的复杂模式和趋势[4]。在这种情况下,LSTM模型可能会自动学习到时间序列的非平稳性,并在预测中进行适当的调整。其作为循环神经网络(RNN)的特殊形式,继承了循…

学习Pytorch深度学习运行AlexNet代码时关于在Pycharm中解决 “t >= 0 t < n_classes” 的断言错误方法

在学习深度学习的过程中&#xff0c;遇到了一个报错&#xff1a; 这跑的代码是AlexNet的代码实现。 运行时出现报错&#xff1a; C:\cb\pytorch_1000000000000\work\aten\src\ATen\native\cuda\Loss.cu:257: block: [0,0,0], thread: [4,0,0] Assertion t > 0 && t…