从WebCam获取帧

时间:2013-12-05 10:45:14

标签: c# camera

我正在使用MetriCam库中的WebCam类,我需要定期从我的WebCam获取帧,有谁知道怎么做? 这是我已有的代码:

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
    }
}

2 个答案:

答案 0 :(得分:0)

尝试快速绘制位图时可能会遇到问题。 200ms延迟只会使这些问题不太可能,但并没有真正解决它。您可以尝试使用此代码跳过无法绘制的帧:

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;
    }
}
}

答案 1 :(得分:0)

您可以根据需要创建DispatcherTimer。这是一个定时器中断。

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();
}