EmguCV学习笔记 VB.Net 9.2 VideoWriter类

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

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.rhkb.cn/news/417907.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++一个数因子和(快速求解)

void 一个数因子和(int 整数) {//缘由https://ask.csdn.net/questions/1054457#answer_1251715int he 0, j 0; string a "";while (j < 整数)if (!(整数%j))he j, a to_string(j) "";cout << a << "的因子和&#xff1a;" …

Opencv中的直方图(1)计算反向投影直方图函数calcBackProject()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算直方图的反向投影。 cv::calcBackProject 函数计算直方图的反向投影。也就是说&#xff0c;类似于 calcHist&#xff0c;在每个位置 (x, y)…

ITK-高斯滤波

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 高斯滤波原理 高斯滤波&#xff08;Gaussian Blur&#xff09;是数字图像处理中常见的一种平滑滤波器&#xff0c;旨在通过模糊处…

OpenCV结构分析与形状描述符(10)检测并提取轮廓函数findContours()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在二值图像中查找轮廓。 该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具&#xff0c;可用于形状分析和对象检测与识别。参见 OpenC…

Linux下安装MySQL8.0

一、安装 1.下载安装包 先创建一个mysql目录&#xff0c;在将压缩包下载到此 # 下载tar包 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz等待下载成功 2.解压mysql8.0安装包 tar xvJf mysql-8.0.20-linux-glibc2.12-x86…

visual studio 2022更新以后,之前的有些工程编译出错,升级到Visual studio Enterprise 2022 Preview解决

系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 今天遇到一个问题&#xff1a;visual studio 2022升级成预览版以后&#xff0c;之前的有些工程编译出错。首先代码、项目设置都没有改变&#xff0c;只是更新了visual studio 2022。 在编译工程时&#xff0c;编译器…

Mybatis概述

目录 MyBatis环境搭建 1.创建一张表和表对应的实体类 2.导入MyBatis jar包&#xff0c;mysql 数据库驱动包 3.创建MyBatis全局配置文件 4.定义接口 5.创建sql映射文件 6.测试MyBatis 读取配置文件 创建SqlSeessionFactory 创建SqlSession 获得接口代理对象 MyBatis-D…

集成电路学习:什么是RTOS实时操作系统

RTOS&#xff1a;实时操作系统 RTOS&#xff0c;全称Real Time Operating System&#xff0c;即实时操作系统&#xff0c;是一种专为满足实时控制需求而设计的操作系统。它能够在外部事件或数据产生时&#xff0c;以足够快的速度进行处理&#xff0c;并在规定的时间内控制生产过…

【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件

目录 目标 准备工作 爬取数据的开始时间和结束时间 爬取数据并解析 将数据转换为DataFrame并保存为CSV文件 本文将介绍如何使用Python编写一个简单的爬虫程序,以爬取珠海市2011年至2023年的天气数据,并将这些数据保存为CSV文件。我们将涉及到以下知识点: 使用r…

VMEMMAP分析

VMEMMAP分析 前言代码分析memblocks_presentmemory_presentsparse_index_init first_present_section_nrsparse_init_nid__populate_section_memmappfn_to_page和page_to_pfnvmemmap_populatevmemmap_pgd_populatevmemmap_pud_populatevmemmap_alloc_block_zero问&#xff1a;什…

软件测试永远的家——银行测试,YYDS

为什么做金融类软件测试举个栗子&#xff0c;银行里的软件测试工程师。横向跟互联网公司里的测试来说&#xff0c;薪资相对稳定&#xff0c;加班少甚至基本没有&#xff0c;业务稳定。实在是测试类岗位中的香饽饽&#xff01; 一、什么是金融行业 金融业是指经营金融商品的特…

网络安全售前入门09安全服务——安全加固服务

目录 1.服务概述 2.流程及工具 2.1服务流程 2.2服务工具 3.服务内容 ​​​​​​​4.服务方式 ​​​​​​​5.风险规避措施 ​​​​​​​6.服务输出 1.服务概述 安全加固服务是参照风险评估、等保测评、安全检查等工作的结果,基于科学的安全思维方式、长期的安全…

骨灵冷火!Solon Cloud Gateway 照面发布

骨灵冷火&#xff0c;是练药的好火哟。极冷&#xff0c;又极热。在冰冻中被烧死&#xff1a;&#xff09; 1、认识 Solon Cloud Gateway Solon Cloud Gateway 是基于 Solon Cloud、Vert.X 和 Solon Rx(reactive-streams) 接口实现。小特点&#xff1a; 纯响应式的接口体验流…

坐牢第三十六天(QT)

自定义QQ界面 wedget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> //qt中信息调试类 #include <QIcon> //图标类 #include <QPushButton>//按钮类 #include <QLabel> //标签类 #include <QMovie> //动图类…

树莓派外设驱动WiringPi库

树莓派外设驱动WiringPi库 文章目录 树莓派外设驱动WiringPi库一、树莓派安装WiringPi库二、WiringPi库的使用方法 一、树莓派安装WiringPi库 wiringPi库其实已经很熟悉了&#xff0c;在香橙派中大量使用过&#xff0c;这个库中集成了很多使用的功能性函数&#xff0c;树莓派安…

I2VGen-XL模型构建指南

一、介绍 VGen可以根据输入的文本、图像、指定的运动、指定的主体&#xff0c;甚至人类提供的反馈信号生成高质量的视频。它还提供了各类常用的视频生成模型工具&#xff0c;例如可视化、采样、训练、推理、使用图像和视频的联合训练&#xff0c;加速等各类工具和技术。 &quo…

docker 介绍以及常用命令

文章目录 Docker 概述docker 概念安装 Docker核心概念Docker 镜像Docker 容器Docker 仓库 docker 与虚拟机比较 Docker 命令docker 进程相关命令镜像相关命令查看本地镜像搜索镜像拉取/推送镜像删除镜像 容器相关命令创建容器查看容器启动/终止/删除容器新建并启动容器进入容器…

92. UE5 GAS RPG 使用C++创建GE实现灼烧的负面效果

在正常游戏里&#xff0c;有些伤害技能会携带一些负面效果&#xff0c;比如火焰伤害的技能会携带燃烧效果&#xff0c;敌人在受到伤害后&#xff0c;会接受一个燃烧的效果&#xff0c;燃烧效果会在敌人身上持续一段时间&#xff0c;并且持续受到火焰灼烧。 我们将在这一篇文章里…

地平线SuperDrive首秀:千人研发投入,出场即「比肩第一梯队」

作者 |德新 编辑 |王博 8月底&#xff0c;地平线在北京开放了第一批面向媒体的高阶智驾方案SuperDrive体验。 预计到明年第三季度&#xff0c;SuperDrive将伴随主机厂客户的第一款量产车交付。 目前在国内&#xff0c;仅有英伟达和华为两家的平台基础上&#xff0c;有车企向…

webm转换mp4怎么转?分享6种简单好用的转换方法

在日常的视频处理中&#xff0c;将WebM视频转换为MP4格式是一个常见的需求。无论是为了兼容性、分享还是编辑&#xff0c;MP4格式都因其广泛的支持和良好的性能而备受欢迎。本文将为大家介绍6种高效方法&#xff0c;有需要的小伙伴快来学习下吧。 方法一&#xff1a;口袋视频转…