Cv2.CvtColor の使い方【OpenCV/C#】色空間をグレースケール・HSVに変換する

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

Cv2.CvtColor の使い方【OpenCV/C#】色空間をグレースケール・HSVに変換する

Cv2.CvtColor は Mat の色空間を変換する関数です。BGR→グレースケール、BGR→HSV など、画像処理パイプラインの入口でほぼ必ず登場します。最小の呼び出しは以下のとおりです。

Cv2.CvtColor(src, dst, ColorConversionCodes.BGR2GRAY);

動作環境

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

基本の使い方

BGR 画像をグレースケールに変換して保存するシンプルなサンプルです。

using OpenCvSharp;

// 入力画像を読み込む(BGR形式)
using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");

// BGR → グレースケール に変換
using var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

// 結果を保存
Cv2.ImWrite("output_gray.jpg", gray);

Console.WriteLine($"変換後チャンネル数: {gray.Channels()}"); // 1

実行すると以下がコンソールに表示され、output_gray.jpg が出力されます。

変換後チャンネル数: 1

コード解説

ポイント
ImRead(..., ImreadModes.Color) 常に 3ch BGR で読み込む
new Mat() 出力用 Mat は空で渡す。サイズ・型は自動設定される
ColorConversionCodes.BGR2GRAY 変換コードを列挙体で指定。可読性が高い
gray.Channels() グレースケールなので戻り値は 1

引数と戻り値

void Cv2.CvtColor(Mat src, Mat dst, ColorConversionCodes code, int dstCn = 0)
引数 説明
src Mat 入力画像
dst Mat 出力画像(サイズ・型は自動決定)
code ColorConversionCodes 色空間変換コード(後述)
dstCn int 出力チャンネル数。0 で自動(通常は省略)

戻り値は void。変換結果は dst に書き込まれます。

よく使う ColorConversionCodes

コード 変換内容
BGR2GRAY BGR → グレースケール(1ch)
GRAY2BGR グレースケール → BGR(3ch)
BGR2HSV BGR → HSV
HSV2BGR HSV → BGR
BGR2Lab BGR → CIE L*a*b*
BGR2YCrCb BGR → YCbCr

⚠️ OpenCV の既定読み込み形式は BGR(RGB ではない)。RGB2GRAY ではなく BGR2GRAY を使います。

実践例

HSV に変換して特定色をマスク抽出する

色抽出・色追跡でよく使われるパターンです。HSV 空間に変換してから Cv2.InRange で色域を絞ります。

using OpenCvSharp;

// 入力画像を BGR で読み込む
using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");

// BGR → HSV に変換
using var hsv = new Mat();
Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV);

// 赤色の HSV 範囲でマスクを生成(低域側)
using var mask1 = new Mat();
Cv2.InRange(hsv,
    new Scalar(0, 100, 100),
    new Scalar(10, 255, 255),
    mask1);

// 赤色の HSV 範囲でマスクを生成(高域側)
using var mask2 = new Mat();
Cv2.InRange(hsv,
    new Scalar(160, 100, 100),
    new Scalar(180, 255, 255),
    mask2);

// 2つのマスクを合成
using var mask = new Mat();
Cv2.BitwiseOr(mask1, mask2, mask);

// マスクを適用して赤色領域だけを抽出
using var result = new Mat();
Cv2.BitwiseAnd(src, src, result, mask);

Cv2.ImWrite("output_red.jpg", result);
Console.WriteLine("赤色領域の抽出が完了しました");

実行すると赤色領域だけが残った画像が output_red.jpg に保存されます。

赤色領域の抽出が完了しました

HSV 空間で色を扱う場合、赤は H 値がゼロ付近と 180 付近にまたがるため、2つの範囲を合成するのが定石です。


グレースケール画像を 3ch に戻してカラー描画に備える

アノテーション(矩形・テキスト描画)を加えたい場合、グレースケール Mat は 1ch なので描画関数で色が扱えません。一度 BGR に戻します。

using OpenCvSharp;

using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");

// グレースケールに変換
using var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

// 1ch → 3ch に戻す(色付き描画のため)
using var grayBgr = new Mat();
Cv2.CvtColor(gray, grayBgr, ColorConversionCodes.GRAY2BGR);

// グレー背景に赤い矩形を描画
Cv2.Rectangle(grayBgr, new Rect(50, 50, 200, 150), new Scalar(0, 0, 255), 3);

Cv2.ImWrite("output_annotated.jpg", grayBgr);
Console.WriteLine("アノテーション付き画像を保存しました");
アノテーション付き画像を保存しました

つまずきポイント

⚠️ BGR2GRAY と RGB2GRAY の混同

OpenCV は画像を BGR 順で保持します。Cv2.ImRead で読んだ画像に RGB2GRAY を適用すると、R と B チャンネルの重みが入れ替わり、微妙に異なるグレー値になります。ImRead 経由の画像には必ず BGR2GRAY を使ってください。

⚠️ グレースケール Mat への色指定が無効になる

1ch の Mat(グレースケール)に Cv2.Rectangle 等で new Scalar(0, 0, 255) を指定しても赤色にはなりません。1ch の場合は明度値(0〜255 の整数)しか扱えないためです。カラー描画が必要なら GRAY2BGR で 3ch に変換してから行います。

⚠️ using を省略した Mat のメモリリーク

Cv2.CvtColor の出力 dst に渡す new Mat() は、ネイティブヒープにメモリを確保します。using を付け忘れると GC が回収するまでメモリが解放されず、ループ処理などで顕著なリークになります。出力 Mat は必ず using var dst = new Mat(); と宣言してください。

関連する関数

  • Cv2.InRange — HSV 変換後の色域抽出に組み合わせる定番関数
  • Cv2.Split — 変換後の Mat をチャンネルごとに分離して個別処理する
  • Cv2.ImRead / Cv2.ImWrite — 読み込み・保存の基本操作

まとめ

Cv2.CvtColorColorConversionCodes 列挙体で変換コードを指定するだけで色空間を切り替えられます。OpenCV は BGR 基準であることを常に意識し、用途に応じてグレースケール・HSV を使い分けてください。出力 Mat の using 宣言はメモリリーク防止のために必須です。

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

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

→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

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