C#によるUSBカメラ操作

あちこちの投稿であるようですが、「動かない!」とのお怒りもあるようですので、
動くものを紹介したいと思います。

AForge.NETというライブラリを使います。
Nugetからは
PM> package-install AForge.Video
PM> package-install AForge.Video.DirectShow
を実行しておいてください。

相変わらず、わかりやすさを重視してWindows Formsで作成します。

プロジェクト構成はシンプルにファイル3つ。
0224projectの中身

メインとなる cameraDeviceControl.cs の構成をご紹介します。

概観はこんな感じです。

usercontrolの概観

using System;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;

namespace TestForms
{
    public partial class cameraDeviceControl : UserControl
    {
        private FilterInfoCollection videoDevices;
        private VideoCaptureDevice videoSource;
        public event NewFrameEventHandler NewFrameGot = delegate { };

        public cameraDeviceControl()
        {
            InitializeComponent();
            UpdateConnectingStatus(false);
        }

        public void ReloadCameraDevices()
        {
            try
            {
                TryReloadCameraDevices();
            }
            catch (ApplicationException e)
            {
                statusLabel.Text = e.Message;
            }
        }

        private void TryReloadCameraDevices()
        {
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            if (videoDevices.Count == 0)
            {
                throw new ApplicationException("No device.");
            }
            UpdateDeviceNames();
        }

        private void UpdateDeviceNames()
        {
            deviceListcomboBox.Items.Clear();
            foreach (FilterInfo device in videoDevices)
            {
                deviceListcomboBox.Items.Add(device.Name);
            }
            deviceListcomboBox.SelectedIndex = 0;   // make default to first cam.
        }

        private void deviceListcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool existAvailableDevice = videoDevices != null && videoDevices.Count != 0;
            if (!existAvailableDevice)
            {
                return;
            }
            string targetMoniker = videoDevices[deviceListcomboBox.SelectedIndex].MonikerString;
            videoSource = new VideoCaptureDevice(targetMoniker);
            connectButton.Enabled = true;
        }

        private void connectButton_Click(object sender, EventArgs e)
        {
            videoSource.NewFrame += NewFrameGot;
            videoSource.Start();
            UpdateConnectingStatus(true);
        }

        private void disconnectButton_Click(object sender, EventArgs e)
        {
            if (videoSource == null) return;
            if (!videoSource.IsRunning) return;
            videoSource.NewFrame -= NewFrameGot;
            videoSource.SignalToStop();
            UpdateConnectingStatus(false);

        }

        private void UpdateConnectingStatus(bool isStart)
        {
            statusLabel.Text = isStart ? "Running.." : "Stopped.";
            deviceListcomboBox.Enabled = !isStart;
            connectButton.Enabled = !isStart && deviceListcomboBox.SelectedIndex>=0;
            disconnectButton.Enabled = isStart;
        }
    }
}

あとはこれをFormに貼り付ければ終いです。
Formには上で作ったUserControl(名前はcamDeviceControl)とpictureBoxの2つだけを張っています。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace TestForms
{
    public partial class TestForm : Form
    {
        public TestForm()
        {
            InitializeComponent();
        }

        private void TestForm_Shown(object sender, EventArgs e)
        {
            camDeviceControl.ReloadCameraDevices();
            camDeviceControl.NewFrameGot += camDeviceControl_NewFrameGot;
        }

        void camDeviceControl_NewFrameGot(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            if (InvokeRequired)
            {
                var updater = new Action(UpdateDisplayImage);
                try
                {
                    Invoke(updater, eventArgs.Frame);
                }
                catch (ObjectDisposedException)
                {
                    // through.
                }
                return;
            }
            UpdateDisplayImage(eventArgs.Frame);
        }

        private void UpdateDisplayImage(Bitmap img)
        {
            capturedPictureBox.Image = (Bitmap)img.Clone();
        }
    }
}

エラー処理は全体に適当ですが、これだけでUSBカメラを動作させることができます。

起動時(USBカメラがないとcomboboxは空だよ)
起動時
接続時
接続状態

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中