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 }
接下来再录制视频,其关键代码为:
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 }
二、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 }