Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之三 简单动态聚光灯效果

news2025/4/17 9:48:04

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之三 简单动态聚光灯效果

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之三 简单动态聚光灯效果

一、简单介绍

二、简单动态聚光灯效果实现原理

三、简单动态聚光灯效果案例实现简单步骤

四、注意事项


一、简单介绍

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

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

二、简单动态聚光灯效果实现原理

简单动态聚光灯效果,这里视频中出现了彩色的光圈,随着视频的播放在图像的不同位置游走。

原理和实现方法:

  1. 初始化

    • 读取输入视频文件和获取视频的帧率、尺寸。
    • 创建输出视频文件。
  2. 生成聚光灯

    • 在程序开始时,随机生成多盏聚光灯。每盏聚光灯由位置、颜色、移动角度和速度组成。
  3. 逐帧处理

    • 读取输入视频的每一帧。
    • 在每一帧上应用所有聚光灯的效果,并将其叠加到原始帧上。
    • 更新每一盏聚光灯的位置,如果聚光灯到达视频边缘,则随机选择新的移动角度和速度。
  4. 写入输出

    • 将处理后的帧写入输出视频文件。

在这两个函数中,涉及了一些 OpenCV 和 NumPy 的函数,下面是它们的说明:

OpenCV 函数:

  1. cv2.resize()

    • 用于调整图像的大小。
    • 参数:
      • src:输入图像。
      • dsize:输出图像的尺寸。
      • interpolation:插值方法,用于调整图像尺寸。
    • 返回值:调整大小后的图像。
  2. cv2.split()

    • 用于将多通道图像拆分为单通道图像。
    • 参数:输入的多通道图像。
    • 返回值:单通道图像组成的列表。
  3. cv2.merge()

    • 用于将多个单通道图像合并成一个多通道图像。
    • 参数:单通道图像组成的列表。
    • 返回值:合并后的多通道图像。
  4. cv2.VideoWriter()

    • 创建一个视频写入对象,用于将帧写入视频文件。
    • 参数:
      • filename:输出视频文件名。
      • fourcc:视频编码器。
      • fps:帧率。
      • frameSize:视频帧的大小。
    • 返回值:视频写入对象。

NumPy 函数:

  1. np.ones_like()

    • 生成一个与输入数组形状相同的全 1 数组。
    • 参数:输入数组。
    • 返回值:形状相同且元素全为 1 的数组。
  2. np.zeros_like()

    • 生成一个与输入数组形状相同的全 0 数组。
    • 参数:输入数组。
    • 返回值:形状相同且元素全为 0 的数组。
  3. np.round()

    • 对数组中的元素进行四舍五入。
    • 参数:输入数组。
    • 返回值:四舍五入后的数组。
  4. np.power()

    • 计算数组的幂。
    • 参数:输入数组和幂指数。
    • 返回值:幂计算后的数组。

这些函数在实现聚光灯效果的过程中起着重要的作用,通过它们可以对图像进行大小调整、颜色分离、视频写入等操作。

三、简单动态聚光灯效果案例实现简单步骤

1、编写代码,先看看一个聚光灯移动的效果

2、运行效果

3、具体代码

"""
单个聚光等在视频中移动的效果
"""

import cv2
import numpy as np


def apply_spotlight(frame, spotlight_pos):
    """
    在视频帧上应用动态聚光灯效果
    :param frame: 
    :param spotlight_pos: 
    :return: 
    """
    # 创建一个黑色图像,与原始视频帧相同大小
    spotlight_mask = np.zeros_like(frame)

    # 在黑色图像上绘制一个白色的椭圆,模拟聚光灯光圈
    cv2.ellipse(spotlight_mask, spotlight_pos, (100, 100), 0, 0, 360, (255, 255, 255), -1)

    # 将光圈图像与原始视频帧进行叠加
    result_frame = cv2.addWeighted(frame, 1, spotlight_mask, 0.5, 0)

    return result_frame


def main():
    # 打开视频文件
    cap = cv2.VideoCapture('Videos/CatRun.mp4')

    # 获取视频帧率和尺寸
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    # 创建 VideoWriter 对象
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter('output_video.mp4', fourcc, fps, (width, height))

    # 初始化聚光灯位置
    spotlight_pos = (int(width / 2), int(height / 2))

    # 逐帧处理视频
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        # 应用动态聚光灯效果
        frame_with_spotlight = apply_spotlight(frame, spotlight_pos)

        # 写入输出视频
        out.write(frame_with_spotlight)

        # 更新聚光灯位置(示例中简单地沿着视频宽度方向移动)
        spotlight_pos = ((spotlight_pos[0] + 5) % width, spotlight_pos[1])

    # 释放资源
    cap.release()
    out.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

4、编写代码,实现多个聚光灯动态移动效果

5、运行效果

6、具体代码

"""
简单动态聚光灯效果
    1、apply_spotlights(frame, spotlights):
    这个函数用于在视频帧上应用多盏聚光灯效果。
    参数:
        frame:输入的视频帧,是一个 numpy 数组。
        spotlights:包含多盏聚光灯信息的列表。每个聚光灯由位置、颜色、移动角度和速度组成。
    返回值:
        处理后的视频帧,应用了聚光灯效果。

    2、main():
    这个函数是程序的主函数,用于读取输入视频并逐帧处理,添加聚光灯效果后写入输出视频。
    主要步骤:
        读取输入视频文件。
        初始化输出视频文件。
        创建并初始化多盏聚光灯的信息。
        逐帧读取输入视频,应用聚光灯效果并写入输出视频。
        更新每盏聚光灯的位置。
    函数调用:
    调用了apply_spotlights()函数来添加聚光灯效果。
"""

import cv2
import numpy as np
import random
import math


def apply_spotlights(frame, spotlights):
    """
    在视频帧上应用多盏聚光灯效果
    :param frame:
    :param spotlights:
    :return:
    """
    result_frame = frame.copy()

    # 在每一盏聚光灯上叠加光斑
    for spotlight in spotlights:
        spotlight_pos, spotlight_color, _, _ = spotlight  # 保留移动方向和速度,但在此不使用
        spotlight_mask = np.zeros_like(frame)
        cv2.ellipse(spotlight_mask, spotlight_pos, (150, 150), 0, 0, 360, spotlight_color, -1)
        result_frame = cv2.addWeighted(result_frame, 1, spotlight_mask, 0.5, 0)

    return result_frame


def main():
    video_path = "Videos/CatRun.mp4"
    output_path = "Videos/VideoSpotLightEffect.mp4"

    # 打开视频文件
    cap = cv2.VideoCapture(video_path)

    # 获取视频帧率和尺寸
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    # 创建 VideoWriter 对象
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))

    # 初始化聚光灯列表,每一盏聚光灯由位置、颜色、移动角度和速度组成
    spotlights = []
    for _ in range(5):  # 创建5盏聚光灯
        spotlight_pos = (random.randint(0, width - 1), random.randint(0, height - 1))
        spotlight_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        # 随机选择一个移动角度和速度
        angle = random.uniform(0, 2 * math.pi)
        speed = random.randint(3, 10)
        spotlights.append((spotlight_pos, spotlight_color, angle, speed))

    # 逐帧处理视频
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        # 应用多盏聚光灯效果
        frame_with_spotlights = apply_spotlights(frame, spotlights)

        # 写入输出视频
        out.write(frame_with_spotlights)

        # 更新每一盏聚光灯的位置
        for i in range(len(spotlights)):
            # 获取当前聚光灯的位置、颜色、移动角度和速度
            spotlight_pos, spotlight_color, angle, speed = spotlights[i]
            # 根据移动角度和速度更新聚光灯位置
            dx = int(speed * math.cos(angle))
            dy = int(speed * math.sin(angle))
            new_x = min(max(0, spotlight_pos[0] + dx), width - 1)
            new_y = min(max(0, spotlight_pos[1] + dy), height - 1)
            # 如果聚光灯到达视频边缘,随机选择一个新的移动角度和速度
            if new_x in [0, width - 1] or new_y in [0, height - 1]:
                angle = random.uniform(0, 2 * math.pi)
                speed = random.randint(3, 10)
            # 更新聚光灯列表中的聚光灯信息
            spotlights[i] = ((new_x, new_y), spotlight_color, angle, speed)

    # 释放资源
    cap.release()
    out.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

四、注意事项

  1. 聚光灯移动

    • 确保聚光灯移动的速度和角度自然,避免抖动和突然变化,使得效果更真实。
  2. 边界处理

    • 当聚光灯移动到视频边缘时,要确保正确地处理边界情况,防止越界。
  3. 效率优化

    • 考虑到处理视频的效率,尽量使用向量化操作和适当的数据结构,减少循环和不必要的计算。
  4. 颜色随机性

    • 聚光灯的颜色应该是随机生成的,以增加效果的多样性和真实感。
  5. 参数调整

    • 可以调整聚光灯的数量、移动速度范围、移动角度范围等参数,以获得更满意的效果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】树与森林(树的存储结构、森林与二叉树的转化、树与森林的遍历)

目录 树和森林树的存储结构一、树的双亲表示法:二、树的孩子表示法方法一:定长结点的多重链表方法二:不定长结点的多重链表方法三:孩子单链表表示法 三、树的二叉链表(孩子-兄弟)存储表示法 森林与二叉树的转换树和森林的遍历先根…

回溯算法练习day.1

回溯算法 回溯法的作用 递归函数与回溯算法是相辅相成的,回溯法往往在递归函数的“下面” 使用原因:有些问题无法暴力进行搜索,只能通过回溯法来解决,例如 1.组合问题 2.切割问题 3.子集问题 4.排列问题 5.棋盘问题 回溯算法是一…

ubuntu 更改 ssh 默认端口 22 以加固安全

出于加固安全考虑,一般公司会禁用 ssh 的 22 端口号,因此我们需要改为其他端口。 1、ssh 命令行登录 进入台式机,修改 /etc/ssh/sshd_config 文件中的 Port 配置行,将 22 改为 8022,保存修改后,重启 ssh 服…

一起学习python——基础篇(19)

今天来说一下python的如何修改文件名称、获取文件大小、读取文中指定的某一行内容。 1、修改文件名称: import os testPath"D:/pythonFile/test.txt" testPath2"D:/pythonFile/test2.txt" #修改文件名称使用rename方法, #第一个参…

Java文件操作-IO流

一、文件 1.基本概念 文件:文件是保存数据的地方,比如经常使用的word文档,txt文件,excel文件…都是文件。它既可以保存一张图片,也可以保持视频,声音… 文件流:文件在程序中是以流的形式来操…

Java项目-源码!大学生兼职信息系统

大学生兼职信息系统 1、功能介绍1.1、演示视频 2、系统部分功能展示2.1、管理员登录2.2、管理员功能模块2.2.1、轮播图管理2.2.2、招聘信息管理2.2.3、企业信息管理 3、系统概述4、开发环境 1、功能介绍 本文以Java为开发技术,实现了一个大学生兼职信息系统。 功能…

SF506DS-ASEMI开关电源二极管SF506DS

编辑:ll SF506DS-ASEMI开关电源二极管SF506DS 型号:SF506DS 品牌:ASEMI 封装:TO-252 最大平均正向电流(IF):5A 最大循环峰值反向电压(VRRM):600V 最大…

.net框架和c#程序设计第三次测试

目录 一、测试要求 二、实现效果 三、实现代码 一、测试要求 二、实现效果 数据库中的内容&#xff1a; 使用数据库中的账号登录&#xff1a; 若不是数据库中的内容&#xff1a; 三、实现代码 login.aspx文件&#xff1a; <% Page Language"C#" AutoEventW…

MySQL Innodb中 可重复读隔离级别是否能完全规避幻读

一、MySQL 可重复读隔离级别下的幻读 在 MySQL Innodb引擎可重复读隔离级别下&#xff0c;已经尽可能最大程度的规避幻读的问题了&#xff0c;使得大多数情况下&#xff0c;重复读都是可以得到一致的结果。 针对于读数据&#xff0c;可以大致分为两种模式&#xff0c;快照读&…

【最新华为ensp模拟器安装(内含文件下载)】

详细安装步骤 ensp介绍ensp安装需要的软件具体安装步骤查看virtualbox 配置信息是否正确ensp配置相关测试ensp安装是否成功教程亲测没问题&#xff0c;需要的同学点个关注呗。。。。 ensp介绍 ensp是华为路由交换模拟器&#xff0c;目前e.huawei.com上已经下载不到&#xff0c…

二、Flask会话技术和模板语言

Cookie Session # views.py: 路由 + 视图函数 import datetimefrom flask import Blueprint, render_template, request, redirect, session from .models import *# 蓝图 blue = Blueprint(user, __name__)# 首页 可以写两个路由,都是访问同一个函数 @blue.route(/) @blue.ro…

关于机器学习/深度学习的一些事-答知乎问(二)

进化算法与深度强化学习算法结合如何进行改进&#xff1f; &#xff08;1&#xff09;进化算法普遍存在着样本效率低下的问题&#xff0c;虽然其探索度较高&#xff0c;但其本质为全局随机性搜索&#xff0c;需要在整个回合结束后才能更新其种群&#xff0c;而深度强化学习在每…

普乐蛙VR航天体验馆设备VR太空飞船VR元宇宙展厅

三天小长假就要来啦&#xff01;五一假期也即将到来。老板们想捉住人流量这个财富密码吗&#xff1f;那快快行动起来&#xff01;开启VR体验项目&#xff0c;假期赚翻天&#xff01;小编亲测&#xff01;&#xff01;这款设备刺激好玩&#xff0c;想必会吸引各位家长小孩、学生…

v-show和v-if的区别和使用场景(超级详细)

文章目录 一、v-show与v-if的共同点二、v-show与v-if的区别三、v-show与v-if原理分析# v-show原理v-if原理 四、v-show与v-if的使用场景参考文献 一、v-show与v-if的共同点 我们都知道在 vue 中 v-show 与 v-if 的作用效果是相同的(不含v-else)&#xff0c;都能控制元素在页面…

LangChain-25 ReAct 让大模型自己思考和决策下一步 AutoGPT实现途径、AGI重要里程碑

背景介绍 大模型ReAct&#xff08;Reasoning and Acting&#xff09;是一种新兴的技术框架&#xff0c;旨在通过逻辑推理和行动序列的构建&#xff0c;使大型语言模型&#xff08;LLM&#xff09;能够达成特定的目标。这一框架的核心思想是赋予机器模型类似人类的推理和行动能…

js基础知识+练习

一&#xff0c;JavaScript简单了解 1.什么是JavaScript JavaScript简称JS&#xff0c;是较为流行的一种前端编程语言&#xff0c;是一种脚本语言&#xff0c;通过解释器运行&#xff0c;主要在客户端&#xff08;浏览器&#xff09;上运行&#xff0c;现在也可以基于node.js在服…

程序员的故事:麦哲伦死于JAVA之争

程序员的故事&#xff1a;麦哲伦死于JAVA之争 1400年&#xff0c;永乐年间&#xff0c;永乐皇帝七点钟准时上班了&#xff0c;清了清嗓子&#xff0c;问道&#xff1a;大家都到了没有&#xff1f;今天我们开个会&#xff0c;主要是讲一下项目用什么语言&#xff1f; 元朝的时候…

airtest-ios真机搭建实践

首先阅读4 ios connection - Airtest Project Docs 在Windows环境下搭建Airtest对iOS真机进行自动化测试的过程相对复杂&#xff0c;因为iOS的自动化测试通常需要依赖Mac OS系统&#xff0c;但理论上借助一些工具和服务&#xff0c;Windows用户也可以间接完成部分工作。下面是…

Python中的回调函数和C中函数指针什么关系?

你好&#xff0c;我是安然无虞。 Python 回调 在Python中&#xff0c;‘回调函数’ (callback) 是指一个作为参数传递给其它代码的函数。 目的是在后者完成某些操作后调用这个传递进来的函数。 回调允许在执行异步操作或处理事件时通知调用者代码。 回调函数通常用于&#…

家庭网络防御系统搭建-虚拟机安装siem/securityonion网络连接问题汇总

由于我是在虚拟机中安装的security onion&#xff0c;在此过程中&#xff0c;遇到很多的网络访问不通的问题&#xff0c;通过该文章把网络连接问题做一下梳理。如果直接把securityonion 安装在物理机上&#xff0c;网络问题则会少很多。 NAT无法访问虚拟机 security onion虚拟…