Cv2.MedianBlur の使い方【OpenCV/C#(OpenCvSharp)】〜メディアンフィルタで画像のノイズを除去する〜

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

Cv2.MedianBlur の使い方【OpenCV/C#(OpenCvSharp)】〜メディアンフィルタで画像のノイズを除去する〜

Cv2.MedianBlur は、近傍画素の中央値(メディアン)で各画素を置き換えるフィルタ関数です。ガウシアンブラーと異なり、エッジを保ちながらソルト&ペッパーノイズを効果的に除去できます。

Cv2.MedianBlur(src, dst, ksize);

動作環境

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

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


基本の使い方

まずはグレースケール画像にメディアンフィルタを適用する最小構成のプログラムです。

using OpenCvSharp;

// サンプル用グレースケール画像を生成(実際はファイル読み込みで構いません)
using var src = new Mat(256, 256, MatType.CV_8UC1, new Scalar(200));

// ノイズを疑似的に追加(点状の黒ノイズ)
var rng = new Random(42);
for (int i = 0; i < 500; i++)
{
    int x = rng.Next(0, 256);
    int y = rng.Next(0, 256);
    // ソルト&ペッパーノイズ(0 or 255 を点在させる)
    src.Set(y, x, (byte)(rng.Next(2) == 0 ? 0 : 255));
}

using var dst = new Mat();

// メディアンフィルタ適用(カーネルサイズ 5×5)
Cv2.MedianBlur(src, dst, 5);

// 結果を保存
Cv2.ImWrite("median_result.png", dst);

Console.WriteLine("完了: median_result.png に保存しました");

実行すると点状のノイズが除去された画像が median_result.png に保存されます。

完了: median_result.png に保存しました

コードの要点

行 説明
new Mat(256, 256, MatType.CV_8UC1, ...) 動作確認用のグレースケール画像を生成
src.Set(y, x, ...) ランダム座標にソルト&ペッパーノイズを付加
Cv2.MedianBlur(src, dst, 5) カーネルサイズ5でメディアンフィルタを適用
Cv2.ImWrite(...) フィルタ後の画像をファイルに保存

引数と戻り値

void Cv2.MedianBlur(InputArray src, OutputArray dst, int ksize)
引数 型 説明
src InputArray 入力画像(8U・16U・32Fのチャンネル数1/3/4が対象。ksize≧5では8U・16Uの1チャンネルのみ)
dst OutputArray 出力画像(src と同サイズ・同型)
ksize int カーネルサイズ(奇数・3以上)。例: 3, 5, 7

戻り値はありません(void)。

⚠️ ksize は必ず 奇数 を指定してください。偶数を渡すと実行時例外が発生します。また、ksize が5以上の場合、入力は1チャンネルの CV_8U または CV_16U のみサポートされます(OpenCV 4.x 時点)。


実践例

実践例1: カラー画像のノイズ除去

実際の現場では、カメラ画像に混入したノイズをフィルタリングする用途が多いです。カラー画像(3チャンネル)には ksize を3にすることで対応できます。

using OpenCvSharp;

// カラー画像を読み込む
using var src = Cv2.ImRead("input.jpg", ImreadModes.Color);
if (src.Empty())
{
    Console.WriteLine("画像の読み込みに失敗しました");
    return;
}

using var dst = new Mat();

// カラー画像は ksize=3 でメディアンフィルタを適用
Cv2.MedianBlur(src, dst, 3);

Cv2.ImWrite("output_median3.png", dst);
Console.WriteLine("カラー画像フィルタ完了: output_median3.png");

実践例2: カーネルサイズの比較

カーネルサイズによって除去されるノイズの強さが変わります。複数サイズを試して比較するのが実務での定石です。

using OpenCvSharp;

using var src = Cv2.ImRead("noisy_gray.png", ImreadModes.Grayscale);
if (src.Empty())
{
    Console.WriteLine("画像の読み込みに失敗しました");
    return;
}

// ksize 3 / 5 / 7 の結果をそれぞれ保存して比較
foreach (int ksize in new[] { 3, 5, 7 })
{
    using var dst = new Mat();
    Cv2.MedianBlur(src, dst, ksize);
    string filename = $"median_k{ksize}.png";
    Cv2.ImWrite(filename, dst);
    Console.WriteLine($"ksize={ksize} → {filename} に保存");
}

実行すると以下のように出力されます。

ksize=3 → median_k3.png に保存
ksize=5 → median_k5.png に保存
ksize=7 → median_k7.png に保存

カーネルサイズを大きくするほどノイズ除去効果は上がりますが、細かいテクスチャやエッジ部分の情報も失われていきます。用途に応じて適切なサイズを選択してください。


つまずきポイント

⚠️ ksize が5以上のときカラー画像(3チャンネル)でエラーになる

Cv2.MedianBlur は ksize >= 5 のとき、1チャンネルの CV_8U または CV_16U のみサポートしています。カラー画像に大きなカーネルを適用しようとすると OpenCV の内部でアサーションエラーが発生します。カラー画像には ksize=3 を使うか、グレースケールに変換してから処理してください。

// カラー画像を先にグレースケール変換してから大きいカーネルを適用する
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
Cv2.MedianBlur(gray, dst, 7);

グレースケール変換については Cv2.CvtColor の使い方【OpenCV/C#】色空間をグレースケール・HSVに変換する も参照してください。

⚠️ ksize に偶数を渡すと実行時例外

ksize は必ず奇数(3, 5, 7, …)を指定してください。ユーザー入力や計算結果を ksize に使う場合は、渡す前に ksize | 1 などで奇数化する処理を入れると安全です。

int ksize = (userInput % 2 == 0) ? userInput + 1 : userInput;

⚠️ Mat の Dispose 漏れによるネイティブメモリリーク

Mat はアンマネージドリソースを保持するため、using 宣言によって確実に Dispose してください。using を省略すると GC が回収するまでネイティブメモリが解放されず、長時間稼働のシステムでメモリリークに繋がります。


関連する関数


まとめ

Cv2.MedianBlur はソルト&ペッパーノイズの除去に特化したフィルタで、エッジをある程度保ちながらノイズを消せるのが強みです。カーネルサイズは奇数限定で、5以上のときはグレースケール(1チャンネル)のみ対応という制約を押さえておけば実務で迷うことはありません。using による Mat のリソース管理も忘れずに。

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

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

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

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