使用DirectShow.NET从网络摄像头捕获帧

本文关键字:摄像头 网络 DirectShow NET 使用 | 更新日期: 2023-09-27 18:11:02

我是DirectShow的新手,所以这个库的某些部分我不太了解。我已经看到了DxSnap示例,但是我需要在不预览它的情况下捕获帧,以便进一步处理。我该怎么做呢?

使用DirectShow.NET从网络摄像头捕获帧

如果你主要关心的是"访问网络摄像头",而不是"使用DirectShow访问网络摄像头",那么我会看看aforge.net框架。我曾经用DirectShow试过一次,只是为了发现我可以用更少的代码在更短的时间内对多个视频源做同样的事情。

使用DirectShow访问USB摄像机和视频文件

您可以自己构建一个。如果你打开windows sdk 7.0文件夹你可以打开samples> multimedia> directshow>那里应该有一个过滤器文件夹告诉你如何制作通用过滤器并做你想做的

下面是一个例子。如图所示,构建一个Windows窗体。

点击此链接查看WinForm的外观

    WinForm本身命名为Form1
  • "Recording…"标签命名为lblRecording
  • ComboBox命名为cbCameraDevices
  • "停止"按钮名称为button1
  • "复制"按钮名称为button2
  • "开始"按钮名称为btnStartVideo
  • 还有一个名为pictureBox1的pictureBox,其中将显示视频图像。

这些名称让我们将事件处理程序(下面的代码)与相应的控件关联起来。

如果程序成功构建并运行,使用组合框选择可用的源代码。点击"开始"查看视频源。点击"Copy"将图像克隆到剪贴板上。点击"Stop"关闭图片输入。

代码测试使用Microsoft:

  • Windows 10 - X64 (Intel机器)
  • Visual Studio 2017社区
  • 。. NET Framework 4.5。
要构建代码,包含该代码的项目需要有这些引用:
  • AForge.Video.DirectShow
  • AForge。视频
  • AForge

包可以通过NuGet拉入项目。在Visual Studio IDE中:

  1. 工具->
  2. NuGet Package Manager ->

搜索"AForge"并安装相应的软件包。

代码:

using System;
using System.Drawing;
using System.Windows.Forms;
using CameraDevice;
using AForge.Video.DirectShow;
using System.Threading;
namespace CameraCaptureTest3
{
    public partial class Form1 : Form
    {
        CameraImaging camImg;
        bool StopVideo = true;
        Thread thrVideo;
        object mImageLock;
        FilterInfoCollection videoDevices;
        public Form1()
        {
            InitializeComponent();
            camImg = new CameraImaging();
            mImageLock = new object();
            // enumerate video devices
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            cbCameraDevices.Items.Clear();
            foreach(FilterInfo i in videoDevices) cbCameraDevices.Items.Add(i.Name);
        }
        //---------------------------------------------------------
        // VideoRecordin() is meant to be run on a separate thread
        //---------------------------------------------------------            
        private void VideoRecording()
        {
            camImg.videoSource.Start();
            while (!StopVideo)
            {
                lock (mImageLock)
                {
                    Bitmap tmp = (Bitmap)camImg.bitmap.Clone();
                    if (InvokeRequired)
                    {
                        BeginInvoke(new MethodInvoker(() =>
                        {
                            pictureBox1.Image = tmp;
                            pictureBox1.Invalidate();
                        }));
                    }
                    else
                    {
                        pictureBox1.Image = tmp;
                        pictureBox1.Invalidate();
                    }
                }
                Thread.Sleep(33);
            }
            camImg.videoSource.Stop();
        }
        private void btnStartVideo_Click(object sender, EventArgs e)
        {
            StopVideo = false;
            try
            {
                camImg.videoSource = new VideoCaptureDevice(camImg.videoDevices[cbCameraDevices.SelectedIndex].MonikerString);
                thrVideo = new Thread(VideoRecording);
                thrVideo.Start();
                Thread.Sleep(1000);
                lblRecording.Visible = true;
            }
            catch (Exception)
            {
                MessageBox.Show("No camera is chosen.", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            StopVideo = true;
            if (thrVideo != null) thrVideo.Join();
            lblRecording.Visible = false;
            Application.DoEvents();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            StopVideo = true;
            if (thrVideo != null)
                while (thrVideo.ThreadState == ThreadState.Running)
                    Application.DoEvents();
            pictureBox1.Image = null;
            lblRecording.Visible = false;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            Clipboard.SetImage(pictureBox1.Image);
        }
    }
}