Cv2.Flip / Cv2.Rotate の使い方【OpenCV/C#(OpenCvSharp)】〜反転・90度回転〜

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

Cv2.Flip / Cv2.Rotate の使い方【OpenCV/C#(OpenCvSharp)】〜反転・90度回転〜

Cv2.Flip は画像を上下・左右・両方向に反転します。Cv2.Rotate は画像を 90° 単位で回転します。どちらも1行で書けるシンプルな関数ですが、引数の意味を正確に把握しておくと実装でつまずきません。

最小の使用例はこちらです。

Cv2.Flip(src, dst, FlipMode.Y);          // 左右反転
Cv2.Rotate(src, dst, RotateFlags.Rotate90Clockwise); // 時計回り90°

動作環境

  • OpenCV 4.x(OpenCvSharp4)
  • .NET 8 コンソールアプリ
  • NuGet: OpenCvSharp4 + OpenCvSharp4.runtime.win(Windows 実行時)

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

基本の使い方

using OpenCvSharp;

// 入力画像を読み込む(カレントディレクトリに input.jpg を置く)
using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");

// --- Cv2.Flip ---
using var flipH = new Mat();  // 左右反転(Y軸基準)
using var flipV = new Mat();  // 上下反転(X軸基準)
using var flipB = new Mat();  // 両方向反転

Cv2.Flip(src, flipH, FlipMode.Y);
Cv2.Flip(src, flipV, FlipMode.X);
Cv2.Flip(src, flipB, FlipMode.XY);

Cv2.ImWrite("flip_h.jpg", flipH);
Cv2.ImWrite("flip_v.jpg", flipV);
Cv2.ImWrite("flip_both.jpg", flipB);

// --- Cv2.Rotate ---
using var rot90cw  = new Mat();  // 時計回り 90°
using var rot180   = new Mat();  // 180°
using var rot90ccw = new Mat();  // 反時計回り 90°

Cv2.Rotate(src, rot90cw,  RotateFlags.Rotate90Clockwise);
Cv2.Rotate(src, rot180,   RotateFlags.Rotate180);
Cv2.Rotate(src, rot90ccw, RotateFlags.Rotate90Counterclockwise);

Cv2.ImWrite("rotate_90cw.jpg",  rot90cw);
Cv2.ImWrite("rotate_180.jpg",   rot180);
Cv2.ImWrite("rotate_90ccw.jpg", rot90ccw);

Console.WriteLine("完了: 各画像を書き出しました");

実行すると、カレントディレクトリに flip_h.jpg などの計6枚が生成されます。

完了: 各画像を書き出しました

コード解説

行 ポイント
Cv2.Flip(src, flipH, FlipMode.Y) FlipMode.Y は Y 軸(縦軸)を基準にした反転 → 左右ミラー
Cv2.Flip(src, flipV, FlipMode.X) FlipMode.X は X 軸(横軸)を基準にした反転 → 上下ミラー
Cv2.Flip(src, flipB, FlipMode.XY) 両軸で反転 → 180° 回転と等価
Cv2.Rotate(src, rot90cw, RotateFlags.Rotate90Clockwise) 時計回り 90°。出力の幅と高さが入れ替わる
using var ... = new Mat() 出力用 Mat を必ず using で宣言し、スコープ終了時に解放

引数と戻り値

Cv2.Flip

引数 型 説明
src Mat 入力画像
dst Mat 出力画像(src と同サイズ・同型)
flipCode FlipMode 反転方向を指定する列挙体

FlipMode の値

値 意味
FlipMode.X X 軸基準(上下反転)
FlipMode.Y Y 軸基準(左右反転)
FlipMode.XY 両軸(上下・左右)

戻り値: なし(結果は dst に格納)

Cv2.Rotate

引数 型 説明
src Mat 入力画像
dst Mat 出力画像(90°/270° 時は幅高さが入れ替わる)
rotateCode RotateFlags 回転量を指定する列挙体

RotateFlags の値

値 意味
RotateFlags.Rotate90Clockwise 時計回り 90°
RotateFlags.Rotate180 180°
RotateFlags.Rotate90Counterclockwise 反時計回り 90°

戻り値: なし(結果は dst に格納)

実践例

機械学習データ拡張(学習画像を水増しする)

カメラ画像の向きにバリエーションを付けて学習データを拡張するときに定番の処理です。

using OpenCvSharp;

// 元画像1枚から 8 バリエーションを生成する
using var src = Cv2.ImRead("sample.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");

var rotations = new[]
{
    (RotateFlags.Rotate90Clockwise,        "rot90cw"),
    (RotateFlags.Rotate180,                "rot180"),
    (RotateFlags.Rotate90Counterclockwise, "rot90ccw"),
};

// オリジナル + 3 回転 × (反転あり・なし) = 計 8 パターン
int index = 0;
// オリジナルと左右反転の2パターンを基点にする
foreach (var flipMode in new[] { (FlipMode?)null, FlipMode.Y })
{
    using var flipped = new Mat();
    if (flipMode.HasValue)
        Cv2.Flip(src, flipped, flipMode.Value);
    else
        src.CopyTo(flipped);

    // 基点を保存
    Cv2.ImWrite($"aug_{index++}.jpg", flipped);

    // 3 方向回転を保存
    foreach (var (flag, _) in rotations)
    {
        using var rotated = new Mat();
        Cv2.Rotate(flipped, rotated, flag);
        Cv2.ImWrite($"aug_{index++}.jpg", rotated);
    }
}

Console.WriteLine($"拡張画像を {index} 枚生成しました");
拡張画像を 8 枚生成しました

スマートフォン写真の向き補正

EXIF 情報が無視されてカメラ画像が横倒しで取り込まれた場合の補正例です。

using OpenCvSharp;

// 横向き(幅 > 高さ)で取り込まれた画像を縦向きに戻す
using var src = Cv2.ImRead("rotated_photo.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");

using var dst = new Mat();

if (src.Width > src.Height)
{
    // 反時計回り 90° で縦向きに補正
    Cv2.Rotate(src, dst, RotateFlags.Rotate90Counterclockwise);
    Console.WriteLine($"補正前: {src.Width}x{src.Height} → 補正後: {dst.Width}x{dst.Height}");
}
else
{
    src.CopyTo(dst);
    Console.WriteLine("補正不要");
}

Cv2.ImWrite("corrected.jpg", dst);
補正前: 4032x3024 → 補正後: 3024x4032

つまずきポイント

⚠️ FlipMode の X / Y が直感と逆に感じる

「左右反転なのに Y?」と混乱しやすいです。OpenCV の定義は「どの軸を基準に折り返すか」です。Y 軸(縦の中心線)を基準に折り返すと左右が入れ替わります。逆に X 軸(横の中心線)基準が上下反転です。コメントに「左右反転」と書いておく習慣を付けると保守性が上がります。

⚠️ Cv2.Rotate は 90° 単位の専用関数。任意角度には使えない

45° など任意角度を回転したい場合は Cv2.GetRotationMatrix2D + Cv2.WarpAffine の組み合わせが必要です。Cv2.Rotate の RotateFlags には 90°/180°/270° の3種類しかありません。用途を混同しないよう注意してください。任意角度の射影変換については Cv2.WarpPerspective の使い方も参考になります。

⚠️ 90° 回転後は幅と高さが入れ替わる

Cv2.Rotate で Rotate90Clockwise または Rotate90Counterclockwise を指定すると、出力 Mat のサイズが元画像の幅・高さを入れ替えたものになります。後続処理でサイズを仮定したコードがあるとバグの原因になるため、dst.Width / dst.Height を使って動的に取得するようにしてください。

関連する関数

  • Cv2.WarpAffine — アフィン変換行列を使った任意角度の回転・スケーリング
  • Cv2.Transpose — 行列の転置(幅と高さを入れ替え)。Cv2.Flip と組み合わせると 90° 回転を再現できる
  • Cv2.WarpPerspective の使い方 — 射影変換による歪み補正・俯瞰変換

まとめ

Cv2.Flip は FlipMode 列挙体で上下・左右・両方向の反転を指定します。Cv2.Rotate は RotateFlags で 90°/180°/270° の回転を1行で実行できます。どちらも処理後の Mat サイズ変化(90° 回転時)と using による確実な解放を意識することが実装のポイントです。

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

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

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

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