VideoWriter の使い方【OpenCV/C#(OpenCvSharp)】〜動画ファイルを書き出す〜

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

VideoWriter の使い方【OpenCV/C#(OpenCvSharp)】〜動画ファイルを書き出す〜

VideoWriter は処理済みフレームを動画ファイルとして保存するためのクラスです。コーデック・フレームレート・解像度を指定してインスタンスを作れば、Write() を呼ぶだけでフレームを順に書き込めます。

using var writer = new VideoWriter("output.mp4", FourCC.MP4V, 30.0, new Size(640, 480));
writer.Write(frame);

動作環境

  • OpenCvSharp4(OpenCV 4.x 時点の API)
  • NuGet: OpenCvSharp4 / OpenCvSharp4.runtime.win(Windows 実行時)
  • .NET 8 コンソールアプリ想定

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


基本の使い方

ここでは output.mp4 に 5 秒分(150 フレーム)の単色フレームを書き出すシンプルな例を示します。

using OpenCvSharp;

// 出力設定
const string outputPath = "output.mp4";
const double fps = 30.0;
var frameSize = new Size(640, 480);

// VideoWriter を using で確実に解放する
using var writer = new VideoWriter(
    outputPath,
    FourCC.MP4V,   // コーデック: MPEG-4
    fps,
    frameSize
);

if (!writer.IsOpened())
{
    Console.Error.WriteLine("VideoWriter を開けませんでした。コーデックを確認してください。");
    return;
}

// 150 フレーム書き出し(約5秒)
for (int i = 0; i < 150; i++)
{
    using var frame = new Mat(frameSize, MatType.CV_8UC3, new Scalar(0, 120, 200)); // 青系単色

    // フレーム番号をテキストで描画
    Cv2.PutText(
        frame,
        $"Frame {i:D3}",
        new Point(20, 50),
        HersheyFonts.HersheySimplex,
        1.2,
        Scalar.White,
        2
    );

    writer.Write(frame); // フレームを書き込む
}

Console.WriteLine($"書き出し完了: {outputPath}");

実行結果:

書き出し完了: output.mp4

実行後、カレントディレクトリに output.mp4 が生成されます。メディアプレイヤーで再生すると “Frame 000〜149” のテキストが表示された青い動画(約5秒)を確認できます。

コードの要点

箇所 説明
new VideoWriter(path, fourcc, fps, size) 出力ファイルパス・コーデック・FPS・フレームサイズを指定してオープン
writer.IsOpened() オープン失敗を確実に検出。コーデック非対応・パス不正を早期に捉える
writer.Write(frame) Mat をそのまま渡すだけ。フレームサイズは初期化時と一致させること
using var writer ネイティブリソースを確実に解放。最後のフレームもフラッシュされる

引数と戻り値

コンストラクタ

VideoWriter(string filename, int fourcc, double fps, Size frameSize, bool isColor = true)
引数 型 説明
filename string 出力ファイルパス(拡張子でコンテナ形式が決まる)
fourcc int コーデック識別子。FourCC.MP4V 等の定数か VideoWriter.FourCC() で生成
fps double フレームレート(例: 30.0)
frameSize Size フレームの幅・高さ(書き込む Mat と一致させること)
isColor bool true: カラー / false: グレースケール(省略時 true)

よく使うコーデック定数(FourCC)

定数 説明
FourCC.MP4V MPEG-4(.mp4)
FourCC.H264 H.264(環境依存・要確認)
FourCC.XVID Xvid(.avi)
FourCC.MJPG Motion JPEG(.avi・互換性が高い)
FourCC.DIV3 / FourCC.DIVX DivX 系(.avi)

⚠️ 利用できるコーデックは OS・インストール済みコーデックに依存します。互換性が最も高いのは FourCC.MJPG(AVI)です。

Write メソッド

void Write(Mat image)

フレームを 1 枚書き込みます。image のサイズ・チャンネル数はコンストラクタの設定と一致させてください。


実践例

実践例 1: カメラ映像を加工して動画保存する

カメラから取得したフレームをグレースケール変換してから保存する典型パターンです。

using OpenCvSharp;

const string outputPath = "camera_gray.avi";
const double fps = 30.0;
var frameSize = new Size(640, 480);

using var cap = new VideoCapture(0); // デフォルトカメラ
cap.Set(VideoCaptureProperties.FrameWidth, frameSize.Width);
cap.Set(VideoCaptureProperties.FrameHeight, frameSize.Height);

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

// グレースケール保存なので isColor: false
using var writer = new VideoWriter(outputPath, FourCC.MJPG, fps, frameSize, isColor: false);

if (!writer.IsOpened())
{
    Console.Error.WriteLine("VideoWriter を開けませんでした。");
    return;
}

Console.WriteLine("録画開始(200 フレーム)...");

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

for (int i = 0; i < 200; i++)
{
    cap.Read(frame);
    if (frame.Empty()) break;

    // グレースケールに変換してから書き込む
    Cv2.CvtColor(frame, gray, ColorConversionCodes.BGR2GRAY);
    writer.Write(gray);
}

Console.WriteLine($"録画完了: {outputPath}");

ポイント: グレースケール動画を保存する場合はコンストラクタの isColor: false を忘れずに設定してください。isColor と実際のフレームチャンネル数が食い違うと書き込みが失敗します。


実践例 2: 連番画像から動画を生成する

検査システムなどで連番画像として保存したフレームを後でまとめて動画化する用途です。

using OpenCvSharp;

// 連番画像が "frames/frame_000.png" 〜 "frames/frame_049.png" にあると仮定
const string inputDir = "frames";
const string outputPath = "slideshow.mp4";
const double fps = 10.0;

// 最初の画像からフレームサイズを取得
string firstFile = Path.Combine(inputDir, "frame_000.png");
using var firstFrame = Cv2.ImRead(firstFile);
if (firstFrame.Empty())
{
    Console.Error.WriteLine($"画像が見つかりません: {firstFile}");
    return;
}
var frameSize = new Size(firstFrame.Width, firstFrame.Height);

using var writer = new VideoWriter(outputPath, FourCC.MP4V, fps, frameSize);

if (!writer.IsOpened())
{
    Console.Error.WriteLine("VideoWriter を開けませんでした。");
    return;
}

for (int i = 0; i < 50; i++)
{
    string path = Path.Combine(inputDir, $"frame_{i:D3}.png");
    using var img = Cv2.ImRead(path);
    if (img.Empty())
    {
        Console.WriteLine($"スキップ: {path}");
        continue;
    }
    writer.Write(img);
}

Console.WriteLine($"動画生成完了: {outputPath}");

つまずきポイント

⚠️ using を忘れると最後のフレームが欠ける

VideoWriter は内部バッファを持つため、Dispose() が呼ばれるタイミングで残りのデータがフラッシュ・ファイルクローズされます。using を使わず Dispose() も呼ばなかった場合、末尾フレームが書き込まれない・ファイルが破損するケースがあります。必ず using var writer = ... を使ってください。

⚠️ isColor とフレームチャンネル数の不一致

コンストラクタで isColor: false(グレースケール)を指定したのに 3 チャンネルの Mat を Write() に渡すと、出力が真っ暗になったり書き込みがスキップされたりします。逆に isColor: true(デフォルト)で 1 チャンネルを渡した場合も同様です。初期化設定と書き込む Mat のチャンネル数を必ず一致させてください。

⚠️ コーデックが環境依存で動かない

FourCC.H264 や FourCC.MP4V は OS・ランタイムによって動作しないことがあります。IsOpened() が false を返す場合はコーデックを FourCC.MJPG(AVI)に変更するのが最も手軽な回避策です。Linux 環境では追加のコーデックライブラリが必要になる場合もあります。


関連する関数


まとめ

VideoWriter はコーデック・FPS・フレームサイズを指定して Write() を呼ぶだけで動画ファイルを書き出せるシンプルなクラスです。using による確実な解放と、isColor とフレームチャンネル数の一致が実装上の最重要ポイントです。コーデックが動作しない場合はまず FourCC.MJPG(AVI)に切り替えて動作確認してください。

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

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

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

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