C# 从网络摄像头获取帧

C# 从网络摄像头获取帧,c#,camera,C#,Camera,我正在使用MetriCam图书馆的班级网络摄像头,我需要定期从我的网络摄像头中获取帧,有人知道怎么做吗? 以下是我已有的代码: namespace MetriCam_Coding_Example { public partial class Form1 : Form { #region Private Fields private WebCam camera; #endregion #region Construc

我正在使用MetriCam图书馆的班级网络摄像头,我需要定期从我的网络摄像头中获取帧,有人知道怎么做吗? 以下是我已有的代码:

namespace MetriCam_Coding_Example
{
    public partial class Form1 : Form
    {
        #region Private Fields
        private WebCam camera;
        #endregion

        #region Constructor
        public Form1()
        {
            InitializeComponent();
            camera = new WebCam();
        }
        #endregion

        #region Private Methods
        private void buttonConnect_Click(object sender, EventArgs e)
        {
            if (!camera.IsConnected())
            {
                camera.Connect();
                buttonConnect.Text = "&Disconnect";
                backgroundWorker1.RunWorkerAsync();
            }
            else
            {
                backgroundWorker1.CancelAsync();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (!backgroundWorker1.CancellationPending)
            {
                camera.Update();
                pictureBox1.Image = camera.CalcBitmap();
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            camera.Disconnect();
            buttonConnect.Text = "&Connect";
        }
        #endregion
    }
}

在尝试过快地绘制位图时,可能会遇到问题。200毫秒的延迟只会降低这些问题的可能性,但并不能真正解决问题。您可以尝试使用以下代码跳过无法绘制的帧:

namespace TestGUI
{
public partial class TestGUIForm : Form
{
    private IAsyncResult setBMPResult;
    private Webcam;

    private delegate void SetBmpDelegate(Bitmap b);

    /// <summary>
    /// Standard constructor.
    /// </summary>
    public TestGUIForm()
    {
        InitializeComponent();
        this.FormClosing += TestGUIForm_FormClosing;

        cam = new WebCam();
    }

    private void TestGUIForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        backgroundWorkerGetFrames.CancelAsync();
    }

    private void buttonConnect_Click(object sender, EventArgs e)
    {
        if (cam.IsConnected())
        {
            // if we are already connected, just disable the button and cancel the display thread, the actual disconnection takes place in the *_RunWorkerCompleted method.
            buttonConnect.Enabled = false;
            backgroundWorkerGetFrames.CancelAsync();
        }
        else
        {
            // connect the camera and start the display background worker.
            buttonConnect.Enabled = false;
            try
            {
                cam.Connect();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Connection error: " + ex.Message);
                buttonConnect.Enabled = true;
                return;
            }
            buttonConnect.Text = "Disconnect";
            backgroundWorkerGetFrames.RunWorkerAsync();
            buttonConnect.Enabled = true;
        }
    }

    private void backgroundWorkerGetFrames_DoWork(object sender, DoWorkEventArgs e)
    {
        while (!backgroundWorkerGetFrames.CancellationPending)
        {
            // capture a new frame
            cam.Update();
            // get the current frame
            Bitmap bitmap = cam.CalcBitmap();
            // set the picturebox-bitmap in the main thread to avoid concurrency issues (a few helper methods required, easier/nicer solutions welcome).
            this.InvokeSetBmp(bitmap);
        }
    }
    private void InvokeSetBmp(Bitmap bmp)
    {
        if (setBMPResult == null || setBMPResult.IsCompleted)
        {
            setBMPResult = this.BeginInvoke(new SetBmpDelegate(this.SetImage), bmp);
        }
    }

    private void SetImage(Bitmap bitmap)
    {
        Bitmap oldBitmap = (Bitmap)pictureBoxImageStream.Image;
        pictureBoxImageStream.Image = bitmap;
        if (oldBitmap != null && oldBitmap != bitmap)
            oldBitmap.Dispose();
    }

    private void backgroundWorkerGetFrames_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // disconnect camera and re-enable button.
        cam.Disconnect();
        buttonConnect.Text = "Connect";
        buttonConnect.Enabled = true;
    }
}
}
您可以在指定的时间创建一个Dispatcher。这是计时器的中断

DispatcherTimer timer = new DispatcherTimer();

timer.Interval = new TimeSpan(0, 0, 0, 0, 20); // 20ms
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
然后,当计时器滴答作响时,它将在事件中到达,您将从您的相机获得图像

void timer_Tick(object sender, EventArgs e)
{
    camera.Update();
    pictureBox1.Image = camera.CalcBitmap();
}

我创建了一个计时器,每200毫秒从pictureBox1.Image中提取一帧。