【问题标题】:Capturing frames from webcam using DirectShow.NET使用 DirectShow.NET 从网络摄像头捕获帧
【发布时间】:2011-10-13 07:37:58
【问题描述】:

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

【问题讨论】:

    标签: c# .net webcam directshow.net


    【解决方案1】:

    如果您主要关心的是“访问网络摄像头”而不是“使用 DirectShow 访问网络摄像头”,那么我会看看 AForge.NET-Framework。我用 DirectShow 尝试过一次,只是发现我可以用更少的代码在更短的时间内对多个视频源做同样的事情。

    这里是一些示例代码:Access to USB cameras and video files using DirectShow

    【讨论】:

    • 感谢您的回答!但我必须用directshow 来做。我听说过很多关于 AForge 框架的信息,但我的客户想要使用 DirectShow.NET =(
    • 好吧,我猜它最终归结为 DirectShow,所以 AForge 只是简化了这个过程。但这就是您与客户打交道时所得到的:-)
    • 仅供参考,AForge.NET 仅适用于视频(不捕获音频...)
    • @itsho 耻辱我花了一周的时间在一个项目上发现这个库也限制了我捕捉音频
    【解决方案2】:

    你可以自己建造一个。如果您查看 windows sdk 7.0~ 文件夹,您可以转到示例 > 多媒体 > directshow > 应该有一个过滤器文件夹,向您展示如何制作通用过滤器并按照您的意愿进行操作

    【讨论】:

    • 但是如果我要从相机的静止引脚获取图像怎么办?问题是当我启动捕获图时,有一个带有视频预览弹出窗口的窗口。
    • 如果您使用 Video Renderer,则会创建一个弹出窗口。我对您是要捕获到文件还是捕获到程序感到困惑。如果要捕获到文件,可以执行 Camera -> Smart Tee -> AVI Mux -> File Writer。如果要捕获到程序/代码,则必须创建一个过滤器并在过滤器中捕获图像
    【解决方案3】:

    这是一个例子。如图所示构建一个 Windows 窗体。

    Click this link to see how the WinForm looks

    • WinForm 本身被命名为 Form1
    • “正在录制...”标签被命名为 lblRecording
    • ComboBox 被命名为 cbCameraDevices
    • “停止”按钮名称为button1
    • “复制”按钮名称为 button2
    • “开始”按钮名称为btnStartVideo
    • 还有一个名为 pictureBox1 的图片框,将在其中显示视频图像。

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

    如果程序成功构建并运行,请使用组合框选择可用源。点击“开始”查看视频源。单击“复制”将图像复制到剪贴板上。点击“停止”关闭图片供稿。

    代码使用 Microsoft 测试:

    • Windows 10 - X64(英特尔机器)
    • Visual Studio 2017 社区
    • .NET 框架 4.5。

    要构建代码,包含此代码的项目需要有这些参考

    • AForge.Video.DirectShow
    • AForge.Video
    • AForge

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

    1. 工具->
    2. NuGet 包管理器 ->
    3. 管理解决方案的 NuGet 包...

    搜索“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);
            }
        }
    }
    

    【讨论】:

    • CameraImaging 的类型或命名空间名称未找到,我也没有找到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    相关资源
    最近更新 更多