VideoCapture の使い方【OpenCV/C#(OpenCvSharp)】〜カメラ映像を取り込む〜

OpenCV for C#
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイド / C#(OpenCvSharp)セットアップ

VideoCapture の使い方【OpenCV/C#(OpenCvSharp)】〜カメラ映像を取り込む〜

VideoCapture はカメラデバイスや動画ファイルからフレームを取得するクラスです。カメラのインデックス番号(通常は 0)を渡すだけで映像キャプチャを開始でき、Read メソッドでフレームを1枚ずつ取得できます。

using var cap = new VideoCapture(0);
using var frame = new Mat();
cap.Read(frame);

動作環境

  • OpenCV 4.x(OpenCvSharp4)
  • .NET 8 コンソールアプリ(トップレベルステートメント)
  • NuGet: OpenCvSharp4 + OpenCvSharp4.runtime.win(Windows 実行時)

環境構築がまだの方は環境構築ガイドを先にどうぞ。


基本の使い方

カメラ(インデックス 0)から映像を取得し、ウィンドウに表示し続ける最小構成のプログラムです。q キーを押すと終了します。

using OpenCvSharp;

// カメラデバイス 0 を開く
using var cap = new VideoCapture(0);

if (!cap.IsOpened())
{
    Console.WriteLine("カメラを開けませんでした。");
    return;
}

Console.WriteLine("q キーで終了します。");

using var frame = new Mat();

while (true)
{
    // フレームを1枚取得
    if (!cap.Read(frame) || frame.Empty())
        break;

    // ウィンドウに表示
    Cv2.ImShow("Camera", frame);

    // 1ms 待機。q キーで終了
    int key = Cv2.WaitKey(1);
    if (key == 'q' || key == 27) // 27 = Esc
        break;
}

Cv2.DestroyAllWindows();

実行結果:

q キーで終了します。
(カメラ映像がウィンドウ「Camera」にリアルタイム表示される)

コード解説

箇所 説明
new VideoCapture(0) デバイスインデックス 0 のカメラを開く
cap.IsOpened() カメラが正常に開けたか確認する
cap.Read(frame) 次のフレームを frame に書き込む。失敗時は false を返す
frame.Empty() フレームが空(デバイス切断など)のガード
Cv2.WaitKey(1) 1ms 待機しつつキー入力を取得。0 にするとキー待ちになる

引数と戻り値

VideoCapture コンストラクタ(カメラ用)

引数 型 説明
index int カメラデバイスのインデックス(0 が最初のカメラ)
apiPreference VideoCaptureAPIs バックエンドの指定(省略可。例: VideoCaptureAPIs.DSHOW)

cap.Read

引数 型 説明
image Mat 取得したフレームの出力先
戻り値 bool フレーム取得成功なら true

主なプロパティ

プロパティ 説明
IsOpened() デバイスが開いているか
FrameWidth フレームの幅(px)
FrameHeight フレームの高さ(px)
Fps フレームレート(カメラ依存)

実践例

例1: カメラ解像度を設定してキャプチャする

カメラによっては解像度を変更できます。Set メソッドで希望の解像度を指定します。

using OpenCvSharp;

using var cap = new VideoCapture(0);

if (!cap.IsOpened())
{
    Console.WriteLine("カメラを開けませんでした。");
    return;
}

// 解像度を 1280x720 に設定(カメラが対応していない場合は無視される)
cap.Set(VideoCaptureProperties.FrameWidth, 1280);
cap.Set(VideoCaptureProperties.FrameHeight, 720);

Console.WriteLine($"解像度: {cap.FrameWidth} x {cap.FrameHeight}");
Console.WriteLine($"FPS: {cap.Fps}");

using var frame = new Mat();

while (true)
{
    if (!cap.Read(frame) || frame.Empty())
        break;

    Cv2.ImShow("Camera 1280x720", frame);

    if (Cv2.WaitKey(1) == 'q')
        break;
}

Cv2.DestroyAllWindows();

実行結果(例):

解像度: 1280 x 720
FPS: 30

例2: フレームをグレースケール変換してリアルタイム処理する

カメラ入力に対してフレームごとに画像処理を適用する典型的なパターンです。色抽出などの前処理と組み合わせる際にも同じ構造を使います。

using OpenCvSharp;

using var cap = new VideoCapture(0);

if (!cap.IsOpened())
{
    Console.WriteLine("カメラを開けませんでした。");
    return;
}

using var frame = new Mat();
using var gray = new Mat();

while (true)
{
    if (!cap.Read(frame) || frame.Empty())
        break;

    // グレースケールに変換
    Cv2.CvtColor(frame, gray, ColorConversionCodes.BGR2GRAY);

    Cv2.ImShow("Gray", gray);
    Cv2.ImShow("Original", frame);

    int key = Cv2.WaitKey(1);
    if (key == 'q' || key == 27)
        break;
}

Cv2.DestroyAllWindows();

カメラ映像をグレースケールで表示しながら、元のカラー映像も並べて確認できます。色範囲でマスクを作る Cv2.InRange と組み合わせると、リアルタイムの色抽出処理に発展させられます。


例3: フレームを静止画として保存する

s キーを押したタイミングでフレームを PNG に保存する例です。

using OpenCvSharp;

using var cap = new VideoCapture(0);

if (!cap.IsOpened())
{
    Console.WriteLine("カメラを開けませんでした。");
    return;
}

Console.WriteLine("s キーで保存、q キーで終了します。");

using var frame = new Mat();
int saveCount = 0;

while (true)
{
    if (!cap.Read(frame) || frame.Empty())
        break;

    Cv2.ImShow("Camera", frame);

    int key = Cv2.WaitKey(1);

    if (key == 's')
    {
        string fileName = $"capture_{saveCount++}.png";
        Cv2.ImWrite(fileName, frame);
        Console.WriteLine($"保存しました: {fileName}");
    }
    else if (key == 'q' || key == 27)
    {
        break;
    }
}

Cv2.DestroyAllWindows();

つまずきポイント

⚠️ VideoCapture を using で解放しないとカメラが占有されたままになる

VideoCapture は IDisposable を実装しています。using を書き忘れると、プログラム終了後もカメラデバイスがロックされたまま残ることがあります。using var cap = new VideoCapture(0); を必ず使いましょう。ループ内の Mat も同様です。

// NG: Dispose されない
var cap = new VideoCapture(0);

// OK: スコープ終了時に自動解放
using var cap = new VideoCapture(0);

⚠️ cap.IsOpened() を確認しないとフレームが空のまま処理が進む

カメラが存在しない・他のアプリが占有しているケースで IsOpened() が false になります。確認せずに Read を呼んでも例外にはならず、空の Mat が返るだけで処理がサイレントに失敗します。必ず開通確認を入れてください。


⚠️ Cv2.WaitKey を呼ばないとウィンドウが更新されない

Cv2.ImShow はバッファに描画するだけで、実際にウィンドウを更新するのは Cv2.WaitKey のタイミングです。ループ内で WaitKey を呼ばないと画面が止まったまま(フリーズしているように見える)になります。引数は 1(1ms)が典型的なリアルタイム表示向けの値です。


関連する関数

リアルタイムカメラ映像を取得したあとの処理として、以下の記事が参考になります。

また、カメラ映像と同じ VideoCapture クラスは動画ファイルの読み込みにも使えます(new VideoCapture("video.mp4") のようにパスを渡す)。


まとめ

VideoCapture(0) でカメラを開き、Read でフレームを取得するのが基本パターンです。IsOpened() の確認・using による確実な解放・WaitKey の呼び出しという3点を守れば、リアルタイム映像処理の土台として安定して使えます。取得したフレームはそのまま OpenCvSharp の各処理関数に渡せるため、色抽出・検出・変換など応用の幅は広いです。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。

→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました