如何让百度收录自己的网站信息,如何做推广和引流,WordPress点击特效插件,项目网站建设业务分析版权声明#xff1a;本文为博主原创文章#xff0c;转载请在显著位置标明本文出处以及作者网名#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。
教程VB.net版本请访问…版权声明本文为博主原创文章转载请在显著位置标明本文出处以及作者网名未经作者允许不得用于商业目的。 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.1 VideoCapture类
VideoCapture类是用于处理视频输入的类它提供了多种方法用于从摄像头、视频文件、网络流等不同的源读取视频数据。 9.1.1 构造函数
VideoCapture类提供了2个构造函数
1、Public Sub New (Optional camIndex As Integer 0, Optional captureApi As VideoCapture. API VideoCapture.API.Any)
camIndex要打开的摄像头的编号例如0表示打开第一个摄像头captureApi指定videocapture对象使用的视频捕获API这是一个VideoCapture.API枚举Windows下常用的成员有 Any自动选择最佳的视频捕获APIDShow使用DirectShow视频捕获API。Vfw使用Video for Windows视频捕获API。Ffmpeg使用FFmpeg视频捕获API但是需要安装相应的FFmpeg库。
2、Public Sub New (fileName As String, Optional captureApi As VideoCapture. API VideoCapture.API.Any)
fileName要打开的视频文件路径或网络流地址。captureApi指定videocapture对象使用的视频捕获API。
由于这个构造函数的两个参数均有默认值所以在实际使用中可以使用以下方法
Public Sub New ()
Public Sub New (camIndex As Integer)
Public Sub New (fileName As String) 通常可以采用以下方法来从摄像头或文件获得视频
1、打开本地第一个摄像头
Dim capture As New VideoCapture(0)
2、打开本地视频文件
Dim capture As New VideoCapture (D:\video.mp4)
3、打开网络流
Dim capture As New VideoCapture (http://example.com/video.m3u8) 在EmguCV中VideoCapture类支持许多网络视频协议包括RTSP、HTTP、FTP、MMS等。通过使用不同的网络视频协议可以从远程摄像头、网络摄像头或者网络视频流中获取视频数据。下面分别介绍一下这几种网络视频协议的使用方法。
1. RTSP协议
RTSP协议是一种用于实时数据传输的协议常用于远程视频监控。
Dim capture As New VideoCapture(rtsp://192.168.1.100:554/live.sdp) 打开RTSP视频流
Dim capture As New VideoCapture (rtsp://admin:*** 192.168.1.100:554);
其中的网址是RTSP视频流的URL地址需要根据实际修改。
2. HTTP协议
HTTP协议是一种广泛应用于互联网的协议可以通过HTTP视频流获取网络摄像头或者网络视频流的视频数据。例如
Dim capture As New VideoCapture(http://192.168.1.100:8080/video)
Dim capture As New VideoCapture(http://username:passcam_address/video.cgi? )
其中的网址是HTTP视频流的URL地址需要根据实际修改。
3. FTP协议
FTP协议是一种文件传输协议可以通过FTP视频流获取网络摄像头或者网络视频流的视频数据。
Dim capture As New VideoCapture(ftp://192.168.1.100:21/video.mp4)
其中网址是FTP视频流的URL地址需要根据实际修改。
4. MMS协议
MMS协议是一种多媒体流传输协议可以通过MMS视频流获取网络摄像头或者网络视频流的视频数据。
Dim capture As New VideoCapture(mms://192.168.1.100:1755/video.wmv)
其中网址是MMS视频流的URL地址需要根据实际修改。
注意并非所有的网络视频协议都适用于所有的视频输入设备有些视频输入设备可能不支持某些协议。在使用VideoCapture类打开网络视频流时需要确认网络视频协议是否被支持。可以通过使用VideoCapture的BackendName属性获取VideoCapture类的后端名称以判断是否支持某种网络视频协议。
【代码位置frmChapter9_1】Button1_Click Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 下面测试视频的网址来自https://rtsp.stream/ 可以用以下方法获得 打开https://rtsp.stream/点击Free下的Get started填写邮箱打开邮箱打开指定的链接后会给出2个免费的有效地址。 Dim vc As New VideoCapture(rtsp://zephyr.rtsp.stream/pattern?streamKey3c1b3e15c8904e1b7eea13468a085b3d) Dim backendName As String vc.BackendName If backendName FFMPEG Then 判断是否支持FFMPEG 如果支持FFMPEG可以使用RTSP、HTTP、FTP、MMS等网络视频协议 End If
End Sub 9.1.2 Get和Set方法
Get和Set方法用于获取或设置视频输入源的相关参数例如视频分辨率、帧率、亮度、对比度等。这两个方法的重要参数是一个CapProp枚举它包含很多重要的成员。例如
1、获得VideoCapture对象视频相关属性
VideoCapture.Get(CapProp.Fps) 获取视频帧率
VideoCapture.Get(CapProp.FrameWidth) 获取视频宽度
VideoCapture.Get(CapProp.FrameHeight) 获取视频高度
VideoCapture.Get(CapProp.FrameCount) 获取视频总帧数
VideoCapture.Get(CapProp.PosFrames) 获取视频当前帧数
VideoCapture.Get(CapProp.PosAvti) 获取视频当前帧的位置的属性值。
2、设置VideoCapture对象视频相关属性
VideoCapture.Set(CapProp.FrameWidth, 640) 设置视频宽度为640像素
VideoCapture.Set(CapProp. FrameHeight,, 480) 设置视频高度为480像素
VideoCapture.Set(CapProp. Fps,, 30) 设置视频帧率为30帧/秒
VideoCapture.Set(CapProp. Brightness, 50) 设置视频亮度为50
VideoCapture.Set(CapProp. Contrast, 50) 设置视频对比度为50
【代码位置frmChapter9_1】Button2_Click 获得视频信息
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim vc As New VideoCapture(C:\learnEmgucv\movie1.mov) Dim width As Double vc.Get(CapProp.FrameWidth) Dim height As Double vc.Get(CapProp.FrameHeight) Dim fps As Double vc.Get(CapProp.Fps) Dim FrameCount As Double vc.Get(CapProp.FrameCount) Dim Brightness As Double vc.Get(CapProp.Brightness) Dim Contrast As Double vc.Get(CapProp.Contrast) Console.WriteLine(视频宽度 width) Console.WriteLine(视频高度 height) Console.WriteLine(视频帧率 fps) Console.WriteLine(视频总帧数 FrameCount) Console.WriteLine(视频亮度 Brightness) Console.WriteLine(视频对比度 Contrast) vc.Dispose()
End Sub 注意并非所有的视频属性都适用于所有的视频输入设备有些视频输入设备可能不支持某些属性比如Brightness、Contrast等属性只适合相机。在使用Set方法设置视频捕获属性时最好先使用Get方法获取当前视频捕获属性的值以便确认是否支持该属性。
【代码位置frmChapter9_1】Button3_Click Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim vc As New VideoCapture(C:\learnEmgucv\movie1.mov) 获取当前视频宽度属性的值 Dim width As Integer vc.Get(CapProp.FrameWidth) 判断是否支持该属性 If width 0 Then 设置视频宽度为640像素 vc.Set(CapProp.FrameWidth, 640) End If vc.Dispose()
End Sub 9.1.3 Retrieve、Read和Queryframe方法
这三种方法都是从视频中获得一幅图像。但是各有区别。
1、Retrieve不能自动读取下一帧需要与Grab方法一起使用。而Grab方法只是获取下一帧的数据到一个用户无法访问的内存区然后使用Retrieve方法根据通道号进行编码读取相应的图像。Read和Queryframe方法取出图像后可以自动转到下一帧图像
2、Retrieve可以返回多通道图像比如使用立体摄像机每一帧会返回两个图像而Kinect会返回四个图像。Read和Queryframe方法不能读取多通道图像。
3、三种方法读取完视频文件最后一帧返回的状态详细请看示例代码
QueryFrameIsNothing(m)True其中m为获得的Mat对象下同读取时m所指向的数据指针DataPointer会变。ReadIsNothing(m)Falsem.IsEmptyTrue读取时m所指向的数据指针DataPointer不会变。RetrieveIsNothing(m)Falsem.IsEmpty False仍然会一直返回最后一帧的图像。因此需要判断是否达到最后一帧即播放的当前帧是否是最后一帧。读取时m所指向的数据指针DataPointer不会变。
由于上述三个方法以及Grab方法的使用都很简单这里不再详述。
【代码位置frmChapter9_1】Button4_Click 播放视频 Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click Dim vc As New VideoCapture(C:\learnEmgucv\movie1.mp4) 判断是否已经打开 If vc.IsOpened False Then Exit Sub End If 获得帧率 Dim fps As Double vc.Get(CapProp.Fps) 获得总的帧数 Dim framecount As Long vc.Get(CapProp.FrameCount) Dim m As Mat New Mat() Dim i As Long 0 While True 读取视频帧图像三种方式: 1、使用GrabRetrieve If vc.Grab() False Then Exit While End If If vc.Retrieve(m) False Then Exit While End If 2、使用Read vc.Read(m) 3、使用QueryFrame m vc.QueryFrame 如果m是空 If IsNothing(m) Then Exit While End If 如果m未包含数据 If m.IsEmpty Then Exit While End If 播放视频两种方式 1、在imagebox1里面播放 显示帧画面 ImageBox1.Image m 必须强制刷新否则只会在结束时显示最后一帧画面 ImageBox1.Refresh() 按照播放的帧率设置间隔时间 Threading.Thread.Sleep(1000 \ fps) 2、使用Imshow来播放 显示帧画面 CvInvoke.Imshow(video, m) 等待按键 CvInvoke.WaitKey(1000 / fps) 判断是否已经是结束的一帧 If i framecount Then Exit While End If i 1 Label1.Text i / framecount 必须强制刷新否则只会看到最后的结果 Label1.Update() End While 如果上述代码中使用了CvInvoke.Imshow来显示视频那么这里应该销毁这个窗口 CvInvoke.DestroyWindow(video) vc.Dispose() Label1.Text 播放结束
End Sub
输出结果如下图所示 图9-1 视频播放 在播放时设置视频播放的起始点可以使用两种方式都需要用到Set方法
1、设置指定帧位置作为起始点
vc.Set(CapProp.PosFrames, 帧位置)
2、设置指定时间位置作为起始点
vc.Set(CapProp.PosMsec, 时间位置)
【代码位置frmChapter9_1】Button5_Click 设置播放起始点 Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click Dim vc As New VideoCapture(C:\learnEmgucv\movie1.mp4) vc.Set(CapProp.FrameWidth, 640) vc.Set(CapProp.FrameHeight, 480) Dim fps As Double vc.Get(CapProp.Fps) Console.WriteLine(vc.Get(CapProp.FrameCount)) If vc.IsOpened False Then Exit Sub End If Dim framecount As Long vc.Get(CapProp.FrameCount) Dim i As Long 0 以下两种方式选其一 1、设置要播放的起始帧的位置 Dim frameIndex As Integer 50 vc.Set(CapProp.PosFrames, frameIndex) 2、设置要播放的事件点的位置注意Set()的第二个参数是毫秒 Dim frameTime As Double 3.0 vc.Set(CapProp.PosMsec, frameTime * 1000) Dim m As Mat New Mat() While True 读取视频帧图像使用Read vc.Read(m) If IsNothing(m) Then Exit While End If If m.IsEmpty Then Exit While End If CvInvoke.Imshow(video, m) 显示图像 CvInvoke.WaitKey(1000 / fps) 等待按键 End While CvInvoke.DestroyWindow(video) vc.Dispose() Label1.Text 播放结束
End Sub 事实上当获得视频帧图像后就可以对这个图像进行处理再显示处理的结果。
【代码位置frmChapter9_1】Button6_Click 简单示例处理图像后输出视频 Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click Dim vc As New VideoCapture(C:\learnEmgucv\movie1.mp4) Dim fps As Double vc.Get(CapProp.Fps) If vc.IsOpened False Then Exit Sub End If Dim framecount As Long vc.Get(CapProp.FrameCount) Dim i As Long 0 Dim m As Mat New Mat() While True vc.Read(m) If IsNothing(m) Then Exit While End If If m.IsEmpty Then Exit While End If 这里使用canny简单示例处理图像 Dim mcanny As New Mat CvInvoke.Canny(m, mcanny, 100, 250, 3) CvInvoke.Imshow(video, mcanny) 显示图像 CvInvoke.WaitKey(1000 / fps) 等待按键 End While CvInvoke.DestroyWindow(video) vc.Dispose() Label1.Text 播放结束
End Sub
输出结果如下图所示 图9-2 处理视频帧并播放 9.1.4 Start、Stop和Pause方法
在EmguCV中videocapture类提供了Start、Stop、Pause等方法用于控制视频的播放和暂停。
Start方法开始播放视频实际是启动grab到一个指定线程。该方法并不会立即开始播放视频而是会将视频设置为播放状态此时将会触发ImageGrabbed事件。
Stop方法停止播放视频实际是停止grabbing线程。
Pause方法暂停播放视频实际是暂停正在运行的grab线程。该方法并不会立即暂停视频播放而是会将视频设置为暂停状态。在Pause方法调用后可以使用read或Grab方法读取视频帧进行处理但是读取的视频帧是暂停状态下的帧图像而不是实时的帧图像。
上述三个方法的使用请参看9.1.5节【ImageGrabbed事件】的示例代码。 9.1.5 ImageGrabbed事件
ImageGrabbed事件会在每一帧图像数据被抓取时触发。使用该事件可以实现对视频流的实时处理。需要注意的是1、ImageGrabbed事件实际已经是在进行Grab所以如果使用Retrieve方法获得图像可以不使用Grab方法2、由于ImageGrabbed事件是在后台线程中执行的因此在事件处理方法中不能直接访问窗体或控件的属性。
【代码位置frmChapter9_1】frmChapter9_Load、Button7_Click、vc1_ImageGrabbed、Button8_Click、Button9_Click Dim vc1 As VideoCapture 帧率 Dim fps As Double 0 Private Sub frmChapter9_Load(sender As Object, e As EventArgs) Handles MyBase.Load 不检查跨线程 Me.CheckForIllegalCrossThreadCalls False End Sub 调用VideoCapture的ImageGrabbed事件 Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click vc1 New VideoCapture(C:\learnEmgucv\movie1.mp4) If vc1.IsOpened False Then MessageBox.Show(打开文件失败) Exit Sub End If 获得帧率 fps vc1.Get(CapProp.Fps) 添加ImageGrabbed事件 AddHandler vc1.ImageGrabbed, AddressOf vc1_ImageGrabbed 启动 vc1.Start() End Sub ImageGrabbed事件这里面进行播放 Private Sub vc1_ImageGrabbed(sender As Object, e As EventArgs) Dim nextframe As New Mat 如果使用Retrieve那么需要检查视频当前播放的位置 vc1.Retrieve(nextframe) 判断是否到达视频结束帧 If vc1.Get(CapProp.PosFrames) vc1.Get(CapProp.FrameCount) Then 停止 vc1.Stop() 释放资源 vc1.Dispose() 取消事件 RemoveHandler vc1.ImageGrabbed, AddressOf vc1_ImageGrabbed 需要跨线程 Label1.Text 播放结束 Exit Sub End If 如果使用read只需要检查该方法的返回值 If vc1.Read(nextframe) False Then 停止 vc1.Stop() 释放资源 vc1.Dispose() 取消事件 RemoveHandler vc1.ImageGrabbed, AddressOf vc1_ImageGrabbed 需要跨线程 Label1.Text 播放结束 Exit Sub End If ImageBox1.Image nextframe Threading.Thread.Sleep(1000 / fps) End Sub 暂停 Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click vc1.Pause() End Sub 停止 Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click vc2.Stop()
End Sub 以下代码模拟了电影中常用的扣除绿幕。
【代码位置frmChapter9_1】Button10_Click、vc2_ImageGrabbed Dim vc2 As VideoCapture Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click vc2 New VideoCapture(C:\learnEmgucv\前景.wmv) If vc2.IsOpened False Then MessageBox.Show(打开文件失败) Exit Sub End If fps vc2.Get(CapProp.Fps) AddHandler vc2.ImageGrabbed, AddressOf vc2_ImageGrabbed vc2.Start() End Sub 模拟绿幕 Private Sub vc2_ImageGrabbed(sender As Object, e As EventArgs) Dim nextframe As New Mat 这里是对视频文件进行检查所以使用read同时检查是否播放完毕 If vc2.Read(nextframe) False Then vc2.Stop() vc2.Dispose() RemoveHandler vc2.ImageGrabbed, AddressOf vc2_ImageGrabbed 跨线程了 Label1.Text 播放结束 Exit Sub End If Dim mhsv As New Mat CvInvoke.CvtColor(nextframe, mhsv, ColorConversion.Rgb2Hsv) 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) Dim mout As New Mat CvInvoke.BitwiseAnd(nextframe, m3channel, mout) Threading.Thread.Sleep(1000 / fps) ImageBox1.Image mout
End Sub
输出结果如下图所示 图9-3 模拟去除绿幕