一.AForge和EmguCV
1.Aforge
Aforge
2.EmguCV
OpenCV(Open Source Computer Vision Library)是一个(开源免费)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android、ios等操作系统上,它轻量级而且高效—由一系列C函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的诸多通用算法。
EmguCV是OpenCV的一个跨平台的.Net封装,由于OpenCV是用C和C++编写的,Emgu用C#对其进行封装,允许用.Net语言来调用OpenCV函数,如C#、VB、VC++等,同时该封装也可以被编译到Mono平台和允许在Windows、Mac OS、Android、iPhone、iPad等多个平台上运行。
OpenCV官网:https://opencv.org/
EmguCV官网:http://www.emgu.com/wiki/index.php/Main_Page
二.AForge获取本地摄像头
三.EmguCV获取本地摄像头/ 播放RTSP地址视频流
1.安装EmguCV
NuGet安装EmguCV:项目引用上右键点击,选择“管理NuGet程序包”。
搜索EmguCV,点击红框的进行安装下载。
安装好后,引用有以下3个关键包:
Emgu.CV.UI:
包含UI组件,用于forms和WPF窗口组件。其中的ImageBox是显示视频流的关键UI。
Emgu.CV.UI.GL:
Emgu.CV.World:
2.WPF实现显示视频流代码
1.建立如下的WPF窗口。
xmal代码如下:
<Window x:Class="RTSP测试.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:RTSP测试"
xmlns:ui="clr-namespace:Emgu.CV.UI;assembly=Emgu.CV.UI"
xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<wfi:WindowsFormsHost Grid.Column="0" Grid.Row="0">
<ui:ImageBox x:Name="img"/>
</wfi:WindowsFormsHost>
<Button x:Name="Open" FontSize="40" Grid.Row="1" Grid.Column="0" Content="打开" Click="Open_Click"/>
<Button x:Name="Start" FontSize="40" Grid.Row="1" Grid.Column="1" Content="开始" Click="Start_Click"/>
<Button x:Name="RTSP" FontSize="40" Grid.Row="0" Grid.Column="1" Content="RTSP" Click="RTSP_Click"/>
</Grid>
</Window>
注意:
这里要引用两个命令空间:
xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
这个空间时包含WindowsFormsHost组件,用于放置一些图片,视频播放器的UI控件(我只会这么用)。
xmlns:ui="clr-namespace:Emgu.CV.UI;assembly=Emgu.CV.UI"
这个空间是ImageBox组件的空间。IamgeBox是EmguCV的播放视频组件。
后台代码:
using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Runtime.InteropServices;
namespace RTSP测试
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
#region CV相关
//emguCV捕捉视频信息的类
Capture capture;
//RTSP视频流地址
string RTSPStream = "rtsp地址";
private Bgr f = new Bgr(System.Drawing.Color.Red);
//================初始化capture,用于打开按钮调用=======================
public void InitCamera()
{
//将capture实例化,没有任何参数的实例化将会读取本地摄像头
capture = new Capture();
//捕捉图片时调用的事件
capture.ImageGrabbed += Capture_ImageGrabbed;
}
/// <summary>
/// 捕获图像的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Capture_ImageGrabbed(object sender, System.EventArgs e)
{
Mat frame = new Mat();
capture.Retrieve(frame, 0);
img.Image = frame;
}
#endregion
#region 控件事件
private void Open_Click(object sender, RoutedEventArgs e)
{
InitCamera();
}
private void Start_Click(object sender, RoutedEventArgs e)
{
if (capture != null)
{
if ((string)Start.Content == "停止")
{
//stop the capture
Start.Content = "开始";
capture.Pause();
}
else
{
//start the capture
Start.Content = "停止";
capture.Start();
}
}
}
private void RTSP_Click(object sender, RoutedEventArgs e)
{
try
{
//通过地址获取捕捉文件
capture = new Capture(RTSPStream);
//捕捉
capture.ImageGrabbed += Capture_ImageGrabbed;
}
catch
{
}
}
#endregion
}
}
3.运行结果
点击“打开”,启动本地摄像头;
在点击“开始”,开始捕捉画面。成功。
如下:
设置好rtsp地址。
点击“RTSP”,在点击“开始”。
成功如下:
4.对视频标记(用于各类检测)
如图:标记拳头
代码:将Mat文件标记并转为IImage类对象用于显示
//=================将Mat类对象标记并转为IImage对象用于ImageBox显示==============
private IImage Mark(Mat mat)
{
//判断空,否则有个莫名的错误
if (mat==null || mat.Bitmap == null)
{
return null;
}
//将Mat类对象 转化 为可画的类型
Image<Bgr, byte> image = new Image<Bgr, byte>(mat.Bitmap);
//保存检测框的信息
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle
{
//===========此区域进行你的检测框标记===========
X = 100,
Y = 100,
Width = 50,
Height = 50
//===========此区域进行标记=====================
};
//IImage文件画上标记
image.Draw(rectangle, f);
return image;
}```
将图片抓取的代码修改一下,换个函数名字
```c
private void Capture_Mark(object sender, System.EventArgs e)
{
Mat frame = new Mat();
capture.Retrieve(frame, 0);
//处理并且显示图片
img.Image = Mark(frame);
}
加入事件中
public void InitCamera()
{
//将capture实例化,没有任何参数的实例化将会读取本地摄像头
capture = new Capture();
//捕捉图片时调用的事件
capture.ImageGrabbed += Capture_Mark;
}
给“打开”按钮调用
private void Open_Click(object sender, RoutedEventArgs e)
{
InitCamera();
}
————————————————
版权声明:本文为CSDN博主「弥敦道九号技师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45487715/article/details/107915992