Emgucv(二)Emgucv和Aforge录制视频

一、Emgucv录制视频

  Emgucv中的Capture类可以完成视频文件的读取,利用EmguCV播放视频的原理是:将视频看作图片,用capture获取抓取通道,通过不断的调用{frame =
capture.QueryFrame();imageBox1.Image = frame;}语句实现图像的实时显示。

  录制视频时用到了VideoWriter()这个函数,它有两种构造方法,分别为VideoWriter(string fileName, int compressionCode, int fps, int width, int height, bool isColor)和VideoWriter(string fileName, int fps, int width, int height, bool isColor),其中:

  fileName:文件的保存路径;

  compressionCode:视频的编码方式;

  fps:录制视频的帧率;

  width:视频的宽度;

  height:视频的高度;

  isColor:是否是彩色;

最后调用WriteFrame()方法录制视频

  首先我们要做的第一步就是打开电脑自带的摄像头,其代码为:

 1 private Capture capture;
 2         private void btnStart_Click(object sender, EventArgs e)
 3         {
 4             capture = new Capture();
 5             Application.Idle += new EventHandler(processfram);
 6         }
 7         private void processfram(object sender, EventArgs arg)
 8         {  
 9             frame = capture.QueryFrame(); 
10             imageBox1.Image = frame;
11         }
View Code

  接下来再录制视频,其关键代码为:

1 vw = new VideoWriter("E:\\1.avi", CvInvoke.CV_FOURCC('M', 'J', 'P', 'G'), 25,(int)CvInvoke.cvGetCaptureProperty(capture, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH), (int)CvInvoke.cvGetCaptureProperty(capture, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT), true);
2                     Application.Idle += new EventHandler(processfram);

  其完整代码为:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using Emgu.CV;
10 using Emgu.CV.Structure;
11 
12 namespace test
13 {
14     public partial class Form1 : Form
15     {
16         public Form1()
17         {
18             InitializeComponent();
19         }
20         private Capture capture;
21         Image<Bgr, Byte> frame;
22         VideoWriter vw;
23         bool flag = false;
24         private void btnStart_Click(object sender, EventArgs e)
25         {
26             btnRecord.Enabled = true;
27             capture = new Capture();
28             Application.Idle += new EventHandler(processfram);
29         }
30         private void processfram(object sender, EventArgs arg)
31         {  
32             frame = capture.QueryFrame(); 
33             imageBox1.Image = frame;
34             if(flag)
35                 vw.WriteFrame(frame);
36         }
37 
38         private void btnRecord_Click(object sender, EventArgs e)
39         {
40             if (btnRecord.Text == "录制")
41             {
42                 if (MessageBox.Show("开始录制吗?", "Information", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
43                 {
44                     flag = true;
45                     vw = new VideoWriter("E:\\1.avi", CvInvoke.CV_FOURCC('M', 'J', 'P', 'G'), 25,(int)CvInvoke.cvGetCaptureProperty(capture, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH), (int)CvInvoke.cvGetCaptureProperty(capture, Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT), true);
46                     Application.Idle += new EventHandler(processfram);
47                     btnRecord.Text = "暂停";
48                 }
49             }
50             else 
51             {
52                 if (MessageBox.Show("停止录制吗?", "Information", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
53                 {
54                     flag = false;
55                     Application.Idle -= new EventHandler(processfram);
56                     vw.Dispose();
57                     btnRecord.Text = "录制";
58                 }
59             }
60         }
61     }
62 }
View Code


 

二、Aforge录制视频(在上一篇博客的基础上,所以在此之前先看完上一篇博客)

  Aforge录制视频调用的是AVIWriter()函数,所以在此之前先要引入AForge.Video.VFW.dll程序集,其具体步骤如下:

  (1)先new一个AVIWriter对象,如AVIWriter writer = new AVIWriter("wmv3"),此代表的是录制的事avi格式的视频,但是必须先要装个插件,下载地址http://blog.csdn.net/wletv/article/details/9188417,唯一的缺点就是不能64位的系统下运行;如果不加“wmv3”则没有这个问题,可是录制几秒就有一两百兆了,十分的不可取(如果谁有更好的解决办法请及时告诉我哦:));

  (2)接着调用其Open方法,如writer.Open(string fileName, int width, int height),其中fileName为路径,width为宽度,height为高度;

  (3)写入视频文件,调用AddFrame方法;

完整代码为:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using AForge.Video.DirectShow;
 10 using AForge.Video;
 11 using System.Diagnostics;
 12 using AForge.Video.VFW;
 13 
 14 namespace Aforge调用摄像头
 15 {
 16     public partial class Form1 : Form
 17     {
 18         private FilterInfoCollection videoDevices;
 19         private VideoCaptureDevice videoSource;
 20         AVIWriter writer = new AVIWriter();
 21         private Bitmap bitmap,img;
 22         public Form1()
 23         {
 24             InitializeComponent();
 25         }
 26 
 27         private void Form1_Load(object sender, EventArgs e)
 28         {
 29             try
 30             {
 31                 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);//枚举所有的视频输入设备
 32                 if (videoDevices.Count == 0)
 33                     throw new ApplicationException();
 34                 foreach (FilterInfo device in videoDevices)
 35                 {
 36                     cbCapture.Items.Add(device.Name);//把所有的视频设备添加到下拉框中
 37                 }
 38                 cbCapture.SelectedIndex = 0;
 39                 videoSource = new VideoCaptureDevice(videoDevices[cbCapture.SelectedIndex].MonikerString);//摄像头的名称
 40                 videoSource.DesiredFrameSize = new Size(500, 300);//设置大小
 41                 videoSource.DesiredFrameRate = 1;//设置帧率
 42                 videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
 43                 videoSource.Start();
 44             }
 45             catch (Exception ex)
 46             {
 47                 MessageBox.Show(ex.Message);
 48             }
 49         }
 50         private void btnStart_Click(object sender, EventArgs e)
 51         {
 52             videoSource.Stop();
 53             videoSource = new VideoCaptureDevice(videoDevices[cbCapture.SelectedIndex].MonikerString);//摄像头的名称
 54             videoSource.DesiredFrameSize = new Size(500, 300);//设置大小
 55             videoSource.DesiredFrameRate = 1;//设置帧率
 56             videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);  
 57             videoSource.Start();
 58         }
 59         private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
 60         {
 61             bitmap = (Bitmap)eventArgs.Frame.Clone();
 62             pictureBox1.Image = bitmap;
 63         }
 64 
 65         private void btnConfig_Click(object sender, EventArgs e)
 66         {
 67             if ((videoSource != null) && (videoSource is VideoCaptureDevice))
 68             {
 69                 try
 70                 {
 71                     ((VideoCaptureDevice)videoSource).DisplayPropertyPage(this.Handle);
 72                 }
 73                 catch (NotSupportedException ex)
 74                 {
 75                     MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
 76                 }
 77             }
 78         }
 79 
 80         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 81         {
 82             Process p = Process.GetCurrentProcess();
 83             if (p.HasExited == false)
 84             {
 85                 p.Kill();
 86             }
 87         }
 88         private void btnRecord_Click(object sender, EventArgs e)
 89         {
 90             if (btnRecord.Text == "录制")
 91             {
 92                 if (MessageBox.Show("Start Recording?", "Information", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
 93                 {
 94                     writer = new AVIWriter("wmv3");
 95                     writer.Open("E:\\1.avi", bitmap.Width, bitmap.Height);
 96                     videoSource.NewFrame += new NewFrameEventHandler(video_NewFrames);
 97                     btnRecord.Text = "停止";
 98                 }
 99             }
100             else
101             {
102                 if (MessageBox.Show("Stop Recording?", "Information", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
103                 {
104                     writer.Dispose();//不dispose掉会报错,不能是close
105                     btnRecord.Text = "录制";
106                 }
107             }
108         }
109         private void video_NewFrames(object sender, NewFrameEventArgs eventArgs)
110         {
111             img = (Bitmap)eventArgs.Frame.Clone();
112             writer.AddFrame(img);
113         } 
114     }
115 }
View Code

 

posted @ 2013-09-17 23:07  魏政  阅读(5294)  评论(0编辑  收藏  举报