EmguCV学习笔记 VB.Net 9.2 VideoWriter类

news2024/12/23 22:15:19

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。

教程VB.net版本请访问:EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问:EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码,请移步:EmguCV学习笔记

学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客

 学习C#知识,请移步:C# 教程 目录_c#教程目录-CSDN博客

9.2 VideoWriter类

VideoWriter类提供了将帧图像数据保存为视频文件的功能。

9.2.1 构造函数

VideoWriter类常用的1个构造函数:

Public Sub New(fileName As String, compressionCode As Integer, fps As Double, size As System.Drawing.Size, isColor As Boolean)

参数说明:

  1. fileName:保存的视频文件名。如果需要保存的视频文件已经存在,那么videowriter类将会删除原文件,并创建一个新的视频文件。
  2. codecId:视频编解码器的代码,详见9.2.2节【Fourcc方法】。
  3. fps:视频的帧率。
  4. size:视频的宽度和高度。
  5. isColor:是否保存彩色视频。

以下是VideoWriter构造函数的示例代码:

Dim vw As New VideoWriter("C:\saved-movie.mp4", codecId, 25, New Drawing.Size(640, 480), True)

9.2.2 Fourcc方法

Four cc是一个用于指定视频编解码器的4字节代码,是一个由四个ASCII字符组成的标识符。Four cc的作用是告诉计算机如何编解码视频文件并正确地显示它。

常见的编解码器格式对应Four cc如下:

编码

Four cc

编码

Four cc

编码

Four cc

MPEG-4

DIVX

MPEG-1

PTM1

MPEG-4.2

MP42

MPEG-4.3

DIV3

H263

U263

H263I

I263

H.264

AVC1

H.265

HEVC

FLV1

FLV1

编码不同,对电脑性能要求不同,生成文件大小也不同。具体需要哪种编码,要根据实际需求进行综合考虑。

VideoWriter类提供了fourcc静态方法,通过传入的4字符返回一个编解码器的代码。声明如下:

Public Shared Function Fourcc(c1 As Char, c2 As Char, c3 As Char, c4 As Char) As Integer

9.2.3 Write方法

Write方法用于将一帧图像写入视频文件中。该方法声明如下:

Public Sub Write(frame As Emgu.CV.IInputArray)

参数说明:

  1. frame:要写入视频文件的帧,类型为Mat。

write方法只能将一帧图像写入视频文件中。如果需要将多帧图像写入视频文件中,可以在write方法的调用中使用循环来实现。

【代码位置:frmChapter9_1】Button11_Click

    '写入视频文件

    Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click

        Dim vc As New VideoCapture("C:\learnEmgucv\movie1.mp4")

        If vc.IsOpened = False Then

            Exit Sub

        End If

        Dim codecId As Integer

        'Mpeg-4.2编码

        codecId = VideoWriter.Fourcc("M"c, "P"c, "4"c, "2"c)

        '宽度,同源视频文件

        Dim width As Integer = vc.Get(CapProp.FrameWidth)

        '高度,同源视频文件

        Dim height As Integer = vc.Get(CapProp.FrameHeight)

        '帧率,同源视频文件

        Dim movieFps As Double = vc.Get(CapProp.Fps)

        '使用Mpeg-4.2来编码

        Dim vw As New VideoWriter("C:\learnEmgucv\saved-movie.mp4", codecId, 50, New Drawing.Size(width, height), True)

        Dim m As Mat = New Mat()

        While True

            m = vc.QueryFrame

            If IsNothing(m) Then

                Exit While

            End If

            If m.IsEmpty Then

                Exit While

            End If

            ImageBox1.Image = m

            ImageBox1.Refresh()

            '将帧图像输出到文件

            vw.Write(m)

            Threading.Thread.Sleep(1000 \ movieFps)

        End While

        vc.Dispose()

        vw.Dispose()

        Label1.Text = "保存完毕"

End Sub

【代码位置:frmChapter9_1】Button12_Click、Button13_Click

    '是否停止录制视频标记

    Dim stopRecord As Boolean

    '开始录制摄像头视频

    Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click

        Dim vc As New VideoCapture(0)

        If vc.IsOpened = False Then

            Exit Sub

        End If

        Dim codecId As Integer

        'Mpeg-4.2编码

        codecId = VideoWriter.Fourcc("M"c, "P"c, "4"c, "2"c)

        '使用Mpeg-4.2来编码

        Dim vw As New VideoWriter("C:\learnEmgucv\saved-movie1.mp4", codecId, 25, New Drawing.Size(640, 480), True)

        Dim m As Mat = New Mat()

        stopRecord = False

        While stopRecord = False

            m = vc.QueryFrame

            If IsNothing(m) Then

                Exit While

            End If

            If m.IsEmpty Then

                Exit While

            End If

            Dim mout As New Mat

            CvInvoke.Canny(m, mout, 160, 250, 3)

            ImageBox1.Image = mout

            ImageBox1.Refresh()

            '输出到文件

            vw.Write(mout)

            '需要增加doevents,否则会出现不响应

            Application.DoEvents()

        End While

        '必须释放资源

        vc.Dispose()

        vw.Dispose()

        Label1.Text = "保存完毕"

    End Sub

    '停止录制摄像头视频

    Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click

        stopRecord = True

End Sub

事实上,在录制摄像头视频时,即使在循环中加了Application.DoEvents(),程序运行时也会出现卡顿的情况。在实际中最好是在ImageGrabbed事件中进行处理。

【代码位置:frmChapter9_1】Button14_Click、vc3_ImageGrabbed、Button15_Click

    Dim vc3 As VideoCapture

    Dim vw3 As VideoWriter

    '是否停止录制

    Dim stopRecord3 As Boolean = False

    '调用ImageGrabbed进行录制视频

    Private Sub Button14_Click(sender As Object, e As EventArgs) Handles Button14.Click

        vc3 = New VideoCapture(0)

        If vc3.IsOpened = False Then

            MessageBox.Show("打开摄像头失败")

            Exit Sub

        End If

        'stopRecord3 = False

        Dim codecId As Integer

        'Mpeg-4.2编码

        codecId = VideoWriter.Fourcc("M"c, "P"c, "4"c, "2"c)

        vw3 = New VideoWriter("C:\learnEmgucv\saved-movie2.mp4", codecId, 25, New Drawing.Size(640, 480), True)

        '添加ImageGrabbed事件

        AddHandler vc3.ImageGrabbed, AddressOf vc3_ImageGrabbed

        '启动

        vc3.Start()

    End Sub

    'ImageGrabbed事件里面进行录制视频

    Private Sub vc3_ImageGrabbed(sender As Object, e As EventArgs)

        Dim nextframe As New Mat

        If stopRecord3 = True Then

            '取消事件

            RemoveHandler vc3.ImageGrabbed, AddressOf vc3_ImageGrabbed

            '释放资源

            vc3.Dispose()

            vw3.Dispose()

            Label1.Text = "录制结束"

        Else

            '获得视频图像

            vc3.Retrieve(nextframe)

            '输出

            vw3.Write(nextframe)

            ImageBox1.Image = nextframe

            Threading.Thread.Sleep(40)

        End If

    End Sub

    Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click

        stopRecord3 = True

End Sub

【代码位置:frmChapter9_1】Button16_Click、getMask

    '模拟实现绿幕视频和其他视频合并并输出

    '1、为了简化说明,未采用在ImageGrabbed事件中进行处理

    '2、为了取得更好的效果,在实际中还需要考虑对抠图的部分进行边缘处理

    Private Sub Button16_Click(sender As Object, e As EventArgs) Handles Button16.Click

        '前景是一个绿幕视频

        Dim vc1 As New VideoCapture("c:\learnEmgucv\前景.wmv")

        If vc1.IsOpened = False Then

            MessageBox.Show("打开前景文件失败")

            Exit Sub

        End If

        '获得前景视频的帧率

        Dim fps1 As Double = vc1.Get(CapProp.Fps)

        '获得前景文件的帧数

        Dim frames1 As Integer = vc1.Get(CapProp.FrameCount)

        '背景视频

        Dim vc2 As New VideoCapture("c:\learnEmgucv\背景.mp4")

        If vc2.IsOpened = False Then

            MessageBox.Show("打开背景文件失败")

            Exit Sub

        End If

        '获得背景视频的帧率

        Dim fps2 As Double = vc2.Get(CapProp.Fps)

        '获得背景文件的帧数

        Dim frames2 As Integer = vc2.Get(CapProp.FrameCount)

        '输出编码,使用MPEG-4.3

        Dim vfourcc As Integer

        vfourcc = Emgu.CV.VideoWriter.Fourcc("D"c, "I"c, "V"c, "3"c)

        Dim vw As New VideoWriter("c:\learnEmgucv\output-movie.avi", vfourcc, 25, New Size(vc1.Width, vc1.Height), True)

        '输出帧数为两个视频帧数相比较最小的

        Dim maxframecount As Integer = IIf(frames1 > frames2, frames2, frames1)

        For i As Integer = 0 To maxframecount - 1

            Console.WriteLine("处理:" & i)

            '读取前景视频的一帧

            Dim m1 As New Mat

            vc1.Read(m1)

            Dim mmask1 As New Mat

            mmask1 = getMask(m1)

            Dim mfront As New Mat

            CvInvoke.BitwiseAnd(m1, mmask1, mfront)

            '读取背景视频的一帧

            Dim m2 As New Mat

            vc2.Read(m2)

            Dim mmask2 As New Mat

            mmask2 = Not mmask1

            Dim mback As New Mat

            CvInvoke.BitwiseAnd(m2, mmask2, mback)

            Dim mout As New Mat

            mout = mfront + mback

            vw.Write(mout)

            '代码会不定位置出现错误提示:

            'OpenCV: Failed to allocate xxxxx bytes”

            '错误的原因主要是提供的内存不足,无法加载更多数据。

            '解决方法:

            '有些网站提出需要切换到64位编译

            '但是经过测试仍然会出现上述错误

            '最好是把所有资源都释放了(如下)。经测试没有发生错误。

            mmask1.Dispose()

            mmask2.Dispose()

            mfront.Dispose()

            mback.Dispose()

            mout.Dispose()

            Threading.Thread.Sleep(40)

        Next

        vc1.Dispose()

        vc2.Dispose()

        Label1.Text = "输出视频完成"

    End Sub

    '将获得的图像根据颜色范围二值化。

    Private Function getMask(ByVal inputMat As Mat) As Mat

        Dim mhsv As New Mat

        CvInvoke.CvtColor(inputMat, mhsv, ColorConversion.Bgr2Hsv)

        '这里测试的是在这两个颜色范围之间

        Dim lower As New ScalarArray(New MCvScalar(35, 43, 46))

        Dim upper As New ScalarArray(New MCvScalar(77, 255, 255))

        '提取图像中某个颜色范围内的像素

        '颜色值在范围内,则将其设置为白色(255),否则将其设置为黑色(0

        Dim mmask As New Mat

        CvInvoke.InRange(mhsv, lower, upper, mmask)

        '根据实际需要判断是否反转颜色

        Dim mreversalmask As New Mat

        mreversalmask = Not mmask

        '以下代码输出二值图作为mask的彩色图,也就是原图去除了绿色背景

        Dim m3channel As New Mat

        CvInvoke.CvtColor(mreversalmask, m3channel, ColorConversion.Gray2Bgr)

        Return m3channel

End Function

输出结果如下图所示:

图9-4 模拟绿幕抠图生成视频

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

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

相关文章

Android Camera 之 CameraInfo 编码模板(前后置摄像头理解、摄像头图像的自然方向理解)

一、Camera.CameraInfo Camera.CameraInfo 是用于获取设备上摄像头信息的一个类,它提供摄像头的各种详细信息,例如,摄像头的方向、是否支持闪光灯等,以下是它的常用属性 static int CAMERA_FACING_BACK:表示设备的后置…

kubernetes 中 利用yaml文件部署应用

目录 1 用yaml文件部署应用有以下优点 1.1 声明式配置: 1.2 灵活性和可扩展性: 1.3 与工具集成: 2 资源清单参数介绍 2.1 获得资源帮助指令explain 2.2 编写示例 2.2.1 示例1:运行简单的单个容器pod 2.2.2 示例2:运行…

二叉树 - 最大二叉树

654. 最大二叉树 方法一 /*** Definition for a binary tree node.* function TreeNode(val, left, right) {* this.val (valundefined ? 0 : val)* this.left (leftundefined ? null : left)* this.right (rightundefined ? null : right)* }*/ /*** param…

java整合Redission

1.maven仓库查询Redisson并倒入项目 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.35.0</version> </dependency> 2.配置文件&#xff08;采用yml配置方式&…

江协科技STM32学习- P9 OLED调试工具

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

2024年9月5日历史上的今天大事件早读

1885年9月5日 左宗棠病逝福州 1894年9月5日 中国古文字学家容庚出生 1905年9月5日 在中国土地上进行的日俄战争结束 1919年9月5日 可口可乐公司成立 1929年9月5日 上海沙逊大厦落成 1937年9月5日 最大一次纳粹集会在纽伦堡举行 1939年9月5日 汪伪政权设立特务组织“七十六…

vue3安装sass时报错:Embedded Dart Sass couldn‘t find the embedded compiler executable

vue3安装sass&#xff1a; npm install sass --save-dev 引用 <template><div class"c1"><h1>hello</h1></div> </template> <style lang"scss">.c1{background-color:red;h1{color:yellow;}} </style>报…

通信算法之230: 5G随机接入PRACH及长度计算

在介绍超远覆盖特性之前&#xff0c;先需了解一下终端接入网络的基本过程。在任何情况下&#xff0c;终端同网络建立通信&#xff0c;都需通过RACH(随机接入信道)向网络发送一个报文来向系统申请一条信令信道&#xff0c;这就是随机接入的过程。根据3GPP 5G R15标准&#xff0c…

如何禁止 Ubuntu 内核更新 ?

更新系统对于保持它的安全和运行是很重要的&#xff0c;然而有时您可能希望停止内核的更新。如果您需要保持系统稳定&#xff0c;或者特定软件在某个内核版本上运行得最好&#xff0c;那么这将非常有用。 在本指南中&#xff0c;我们将向您展示如何在 Ubuntu 中阻止内核更新。…

基于 Konva 实现Web PPT 编辑器(二)

动画系统 为了实现演示中复杂的动画效果&#xff0c;使用 Animation 类统一管理&#xff1b;切换动画通过 css animation 实现&#xff0c;并且是应用在 konvajs-content 上&#xff0c;动画则通过 gsap 实现&#xff0c;应用在 Konva.Node 上&#xff0c;实现思路如下&#xf…

win12R2安装.NET Framework 3.5

一丶安装原因 因此插件的缺失, 有些软件或系统不支持安装. 二丶安装步骤 1丶下载.NET Framework 3.5 点击插件下载, 提取码: 1995, 下载完成之后解压到想要安装的位置上. 2丶打开 服务器管理器 3丶点击: 管理 -> 添加角色和功能 4丶点击下一步到服务器角色, 选择web服…

SQL的高级查询练习知识点(day24)

目录 1 学习目标 2 基础查询 2.1 语法 2.2 例子 3 条件查询 3.1 含义 3.2 语法 3.3 条件表达式 3.3.1 条件运算符 3.3.2 例子 3.4 逻辑表达式 3.4.1 逻辑运算符 3.4.2 例子 3.5 模糊查询 3.5.1 概述 3.5.2 例子 4 DISTINCT关键字 4.1 含义 4.2 例子 5 总结…

代码随想录算法训练营第五十天 | 98. 所有可达路径

目录 98. 所有可达路径 思路 图的存储 邻接矩阵 邻接表 深度优先搜索 1.确认递归函数&#xff0c;参数 2.确认终止条件 3.处理目前搜索节点出发的路径 方法一&#xff1a; 邻接矩阵写法 方法二&#xff1a;邻接表写法 98. 所有可达路径 题目链接&#xff1a;卡码网题…

2024年第十五届蓝桥杯青少组国赛撞期GESP认证、放弃那个?

昨天蓝桥杯青少组官网发布了速查|第十五届蓝桥杯大赛青少组省赛成绩查询&#xff0c;首先恭喜2024年蓝桥杯青少组省赛一等奖的同学晋级蓝桥杯大赛青少组国赛&#xff0c;蓝桥杯青少组国赛的时间为2024年9月7日&#xff0c;CCF GESP编程能力等级认证也在同一天开始&#xff0c;同…

Linux工具: 查询各种系统数据库和服务的linux命令getent详解

目录 一、概述 二、用法 1、基本语法 &#xff08;1&#xff09;database &#xff08;2&#xff09;key 2、常见的数据库类型 3、获取帮助 三、示例 1. 查询用户账号信息 2. 列出所有用户 3. 查询特定组的信息 4. 列出所有组 5. 查询主机名和 IP 地址映射 6. 列…

vue3中openlayers绘制多个Overlay

项目需求是要在地图上显示多个div&#xff0c;之前使用Overlay绘制单个显示正常&#xff0c;结果绘制多个的时候就显示一个&#xff0c;不过也解决了&#xff0c;下面我就把核心代码贴一下&#xff0c;如果有什么问题可以留言&#xff0c;我就是提供一个思路。 效果图 上面图片…

昂科烧录器支持Fortior Tech峰岹科技的电机驱动专用芯片FU6812V

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中Fortior Tech峰岹科技的高性能电机驱动专用芯片FU6812V已经被昂科的通用烧录平台AP8000所支持。 FU6812V是一款集成电机控制引擎(ME)和8051内核的高性能电机驱动专用芯片&…

Nginx性能调优

为什么是Nginx而不是apache&#xff1f; 轻量级&#xff0c;同样起web服务器&#xff0c;比apache占用更少的内存资源静态处理&#xff0c;Nginx静态处理性能比apache高3倍以上抗并发&#xff0c;Nginx处理请求时异步非阻塞的&#xff0c;而apache则是阻塞型的&#xff0c;在高…

代替STM32L010 STM32G030 CMS8S6990 STM8S003的芯片CW32L010

CW32L010作为一款可以代替STM32L010 STM32G030 CMS8S6990 STM8S003部分型号可以兼容的芯片&#xff0c;其功能上能够和它们相匹配&#xff0c;并且在功能更优秀&#xff0c;其芯片特点在于超低功耗&#xff0c;高精度ADC和主频最高可达到48MHz。 CW32L010是基于eFlash的单芯片低…

AutosarMCAL开发——基于EB Gpt驱动

目录 1.Gpt原理2.EB配置以及接口应用2.1 EB配置2.2 接口应用 3.总结 1.Gpt原理 autosar GPT模块&#xff08;General Purpose Timer&#xff0c;通用定时器&#xff09;主要用于汽车ECU中的时间测量、计数和产生定时中断。它支持单次性和周期性定时器&#xff0c;可以在达到预…