Capturing frames from webcam using DirectShow.NET

28,921

Solution 1

you could build one yourself. If you look into the windows sdk 7.0~ folders you can go to samples > multimedia > directshow > and there should be a filters folder that shows you how to make generic filters and do w/e you want

Solution 2

If your main concern is "access webcam" and not "access webcam with DirectShow", then I would have a look at the AForge.NET-Framework. I tried it with DirectShow once just to find out that I could do the same thing with multiple video sources in less time with less code.

Here is some sample code: Access to USB cameras and video files using DirectShow

Solution 3

Here is an example. Construct a Windows Form as shown in the picture.

Click this link to see how the WinForm looks

  • The WinForm itself is named Form1
  • "Recording ..." label is named lblRecording
  • ComboBox is named cbCameraDevices
  • "Stop" button name is button1
  • "Copy" button name is button2
  • "Start" button name is btnStartVideo
  • There is also a pictureBox named pictureBox1 in which video image will be shown.

These names let us associate the event handlers (code below) with the respective control.

If the program is built successfully and run, use the combobox to select an available source. Click "Start" to see video feed. Click "Copy" to clone the image onto the clipboard. Click "Stop" to close the image feed.

The code was tested using Microsoft:

  • Windows 10 - X64 (Intel machine)
  • Visual Studio 2017 Community
  • .NET Framework 4.5.

To build the code, the project containing this code needs to have these References:

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

The packages can be pulled into the project by NuGet. In Visual Studio IDE:

  1. Tools ->
  2. NuGet Package Manager ->
  3. Manage NuGet Package for Solution...

Search for "AForge" and install the respective packages.

Code:

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);
        }
    }
}
Share:
28,921
Denis Ionov
Author by

Denis Ionov

Updated on July 09, 2022

Comments

  • Denis Ionov
    Denis Ionov almost 2 years

    I am new at DirectShow, so some parts of this library i don't understand well. I already see the example DxSnap, but i need to capture frames without previewing it, for futher processing. How can i do it?

  • Denis Ionov
    Denis Ionov over 12 years
    Thanks for your answer! But i must do it with directshow. I hear a lot about AForge Framework, but my customer whants to do it with DirectShow.NET =(
  • Oli
    Oli over 12 years
    Well, I guess it boils down to DirectShow in the end, so AForge would just simplify the process. But that's what you get when dealing with customers :-)
  • Denis Ionov
    Denis Ionov over 12 years
    but what if i will get images from still pin of camera? The problem is that there is a window with the video previewing pop ups when i start the capture graph.
  • Grant
    Grant over 12 years
    if you use Video Renderer, that will create a window popup. Im confused as to whether you want to capture to a file or capture to a program. if you want to capture to a file you can do Camera -> Smart Tee -> AVI Mux -> File Writer. if you want to capture to a program/code, you would have to create a filter and capture the image in the filter
  • itsho
    itsho over 11 years
    FYI, AForge.NET is good for video only (does not capture audio...)
  • cmario
    cmario almost 8 years
    @itsho shame I spent a week on a project to figure out that this library limits me to capture audio as well
  • Kro
    Kro about 2 years
    The type or namespace name for CameraImaging is not found and I didn't manage to find it.