6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C#Advent Calendar 2023

Day 18

USBカメラを使ってみよう

Last updated at Posted at 2023-12-18

この記事はC# Advent Calendar 2023アドベントカレンダーの18日目です。

C#でWindowsアプリを作成する際に、USBカメラやWebカメラを利用する方法を紹介します。ネットで検索する限り、OpenCVSharpを利用している例が多いのですが、今回は、私が作成したライブラリ「UsbCamera」を紹介します。

「UsbCamera」は、DirectShowを利用して、WinFormsやWPFで、USBカメラ(Webカメラ)を利用するためのライブラリです。プログラムはGitHubで公開されています。リポジトリはこちらです。

ライブラリの特徴

UsbCameraの特徴は以下の通りです。

  • 導入するには、ソースコードを1つあなたのプロジェクトに追加するだけです。(DLL等は必要ありません)
  • WinFormsとWPFの両方に対応しています。
  • チルト・ズーム・ホワイトバランス・露出などの設定を行うことができます。(カメラが対応している必要があります)
  • カメラの撮影ボタンで静止画を撮影することができます。(カメラが対応している必要があります)

導入方法

上記リポジトリからクローンするか、zipファイルをダウンロードしてください。ここでは、zipファイルをダウンロードした場合で解説します。

ダウンロードしたzipを解凍すると、ライブラリ本体である「UsbCamera.cs」と、使い方のサンプルである「SampleProject」フォルダが作成されますので、「UsbCamera.cs」を、あなたのプロジェクトに追加してください。

image.png

今回は、サンプルプロジェクトでその使用例を説明しますので、「SampleProject」フォルダ内にある「UsbCameraSample.sln」を起動してください。

image.png

ソリューションには、2つのプロジェクトが含まれています。「UsbCameraForms」がWinForms用で、「UsbCameraWpf」がWPF用です。

プロジェクトを実行して、動作を確認してみてください。画面に、Webカメラの画像が表示されたはずです。

以後、プログラムの中身を解説します。

基本的な使い方

利用可能なカメラを探す。

// 利用可能なカメラを探す。
string[] devices = UsbCamera.FindDevices();
if (devices.Length == 0) return; // カメラが見つからなかった。

UsbCamera#FindDevices()を呼び出して、PCに接続されているカメラの一覧を取得します。
戻り値はstring[]で、カメラ名の配列が返りますので、この中から、利用したいカメラのインデックス番号を確認します。カメラのインデックス番号は、次の「ビデオフォーマットの作成」や、あとで「UsbCameraクラスのインスタンスを作成する際」に使用します。

ビデオフォーマットの選択。

// ビデオフォーマットの取得。
var cameraIndex = 0; // カメラインデックス番号0番のビデオフォーマットを取得。
var formats = UsbCamera.GetVideoFormat(cameraIndex);

カメラは320x240, 640x480など、複数の画面サイズに対応しているのが普通です。UsbCamera#GetVideoFormat()を呼び出して、カメラが対応しているビデオフォーマットのリストを取得します。
たとえば私が使用しているPCのWebカメラでは、以下のようになりました。

image.png

この中から、利用したい画像のサイズであるビデオフォーマットを探します。例えば、1920x1080サイズのビデオフォーマットを利用する場合は、formats[0]を、UsbCameraクラスのインスタンス作成時に指定します。

UsbCameraクラスのインスタンスを作成。

利用したいカメラのインデックス番号と、ビデオフォーマットを指定して、UsbCameraクラスのインスタンスを作成します。インスタンスを作成したら、camera.Start()で動作を開始します。

// カメラインデックスとビデオフォーマットを指定して、USBカメラクラスのインスタンスを作成
var camera = new UsbCamera(cameraIndex, formats[0]);
camera.Start(); // 動作開始!

画像の取得。

カメラから画像を取得するには、camera.GetBitmap()を呼び出します。

button1.Click += (s, ev) => pictureBox1.Image = camera.GetBitmap();

あとしまつ。

フォームクローズ時など、不要になった時点でcamera.Release()を呼び出してください。

this.FormClosing += (s, ev) => camera.Release(); // release when close.

高度な使い方

WPFで利用する。

ライブラリはデフォルトではWinFormsで利用されることを想定されており、GetBitmap()はSystem.Drawing.Bitmap型の画像を返します。
WPFで利用する場合は、「USBCAMERA_WPF」シンボルを定義すると、GetBitmap()はBitmapSource()型で画像を返すようになります。

image.png

プレビューを表示する。

カメラ画像のプレビューを画面に表示したい場合は、WinFormsとWPFで方法が異なります。

WinFormsの場合は、画面にPictureBoxを配置し、camera.SetPreviewControlでプレビューを表示するPictureBoxを指定してください。

camera.SetPreviewControl(pictureBox1.Handle, pictureBox1.ClientSize);
pictureBox1.Resize += (s, ev) => camera.SetPreviewSize(pictureBox1.ClientSize);

WPFの場合は、プレビュー画像が更新されるたびに呼び出されるcamera.PreviewCapturedでデータバインディングを利用して画像を更新してください。詳しくは、サンプルプロジェクトを参照してください。

camera.PreviewCaptured += (bmp) =>
{
    Preview = bmp;
    OnPropertyChanged("Preview");
};

カメラの撮影ボタンへの対応。

カメラには、通常の動画撮影とは別に、静止画撮影機能をもったものがあります。静止画撮影機能で取得した画像は、一般的に、動画撮影で取得した画像より高解像度なことが多いです。

あなたのカメラに、撮影ボタンが付いていたら、そのカメラは静止画撮影機能に対応している可能性が高いです。静止画撮影機能に対応しているかどうかは、camera.StillImageAvailableで判別できます。ボタンが押されたら、camera.StillImageCapturedがコールバックされます。ボタンの代わりに、camera.StillImageTrigger()を呼び出すことで撮影することもできます。

if (camera.StillImageAvailable)
{
    button.Click += (s, ev) => camera.StillImageTrigger();
    camera.StillImageCaptured += bmp => pictureBox.Image = bmp;
}

カメラプロパティ(チルト・ズーム・ホワイトバランス・露出など)の変更。

カメラが対応していれば、チルト・ズーム・ホワイトバランス・露出などを変更することができます。

カメラプロパティには大きく、CameraControlProperty系(Pan, Tilt, Roll, oom, Exposure, Iris, Focus)と、VideoProcAmpProperty系(Brightness, Contrast, hue, Saturation, Sharpness, Gamma, ColorEnable, WhiteBalance...)があります。

例えば露出(Exposure)を変更する場合は以下のようになります。プロパティはカメラが対応していない場合もありますので、必ずAvailableプロパティを確認してください。

// adjust properties.
var prop = camera.Properties[DirectShow.CameraControlProperty.Exposure];
if (prop.Available)
{
    // get current value
    var val = prop.GetValue();
    // set new value
    var min = prop.Min;
    var max = prop.Max;
    var def = prop.Default;
    var step = prop.Step;
    // set new value
    prop.SetValue(DirectShow.CameraControlFlags.Manual, def);
}

おわりに。

以上、駆け足ですが、UsbCameraライブラリの使い方を説明しました。

近年では多くのノートPCにWebカメラが備わっています。もしあなたのPCにカメラがついていたら、試してみてはいかがでしょうか?

それでは、メリークリスマス!

6
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?