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 環境では追加のコーデックライブラリが必要になる場合もあります。
関連する関数
- VideoCapture — カメラや動画ファイルからフレームを取得するクラス。VideoWriter と組み合わせて「読み込み→処理→書き出し」パイプラインを構成します。
- Cv2.InRange の使い方【OpenCV/C#(OpenCvSharp)】〜色範囲でマスクを作る(色抽出)〜 — フレームごとに色抽出した結果を動画保存するケースでよく使います。
- Cv2.ConnectedComponentsWithStats の使い方【OpenCV/C#(OpenCvSharp)】〜ラベリング処理で連結領域を解析する〜 — 検査システムでラベリング結果をフレームに描画して動画保存する用途で組み合わせます。
まとめ
VideoWriter はコーデック・FPS・フレームサイズを指定して Write() を呼ぶだけで動画ファイルを書き出せるシンプルなクラスです。using による確実な解放と、isColor とフレームチャンネル数の一致が実装上の最重要ポイントです。コーデックが動作しない場合はまず FourCC.MJPG(AVI)に切り替えて動作確認してください。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。
→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

