Cv2.AdaptiveThreshold は、画像内の局所的な輝度に応じて二値化の閾値を自動調整する関数です。均一な照明が確保できないシーン(文書スキャン・基板検査など)で、グローバル閾値の Cv2.Threshold より大幅に安定した結果が得られます。
最小コードはこちらです。
Cv2.AdaptiveThreshold(gray, dst, 255,
AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);
動作環境
- OpenCvSharp4(OpenCV 4.x 系)
- NuGet:
OpenCvSharp4+OpenCvSharp4.runtime.win(Windows実行時) - .NET 8 コンソールアプリ(トップレベルステートメント)
環境構築がまだの方は環境構築ガイドを先にどうぞ。
基本の使い方
以下のサンプルは、グレースケール画像に対して適応的二値化を適用し、結果をファイルに保存します。
using OpenCvSharp;
// 入力画像の読み込み(グレースケール)
using var src = Cv2.ImRead("input.png", ImreadModes.Grayscale);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");
using var dst = new Mat();
// 適応的二値化(ガウシアン重み付き局所平均を閾値として使用)
Cv2.AdaptiveThreshold(
src, // 入力(グレースケール必須)
dst, // 出力
maxValue: 255, // 閾値を超えた画素に割り当てる値
adaptiveMethod: AdaptiveThresholdTypes.GaussianC, // 局所平均の計算方法
thresholdType: ThresholdTypes.Binary, // 二値化タイプ
blockSize: 11, // 局所領域のサイズ(奇数)
c: 2 // 平均から引くオフセット値
);
// 結果を保存
Cv2.ImWrite("output_adaptive.png", dst);
Console.WriteLine("保存完了: output_adaptive.png");
実行すると output_adaptive.png が生成されます。照明ムラがある文書画像でも、文字部分が白抜き(または黒塗り)でくっきり二値化されているのが確認できます。
各引数の役割
blockSize: 11— 各画素の閾値を計算する近傍領域の一辺(奇数のみ)。小さいほど細かい局所変動に追従、大きいほど大局的な明暗に対応します。c: 2— 計算した局所平均から引くオフセット。正の値にするとノイズ除去効果が増し、負にすると逆に感度が上がります。
引数と戻り値
| 引数名 | 型 | 説明 |
|---|---|---|
src |
Mat |
入力画像(8ビットグレースケール必須) |
dst |
Mat |
出力画像(入力と同サイズ・同型) |
maxValue |
double |
条件を満たす画素に設定する値(通常 255) |
adaptiveMethod |
AdaptiveThresholdTypes |
局所平均の計算方式(下表参照) |
thresholdType |
ThresholdTypes |
Binary または BinaryInv のみ有効 |
blockSize |
int |
局所領域サイズ(奇数・3以上) |
c |
double |
局所平均から引くオフセット値 |
戻り値: なし(dst に書き込まれます)
AdaptiveThresholdTypes の選択肢
| 値 | 説明 |
|---|---|
MeanC |
近傍の単純平均 − C を閾値とする |
GaussianC |
近傍のガウシアン重み付き平均 − C を閾値とする。エッジ付近のノイズに強い |
実践例
例1: MeanC と GaussianC の比較出力
using OpenCvSharp;
using var src = Cv2.ImRead("document.png", ImreadModes.Grayscale);
if (src.Empty()) throw new Exception("画像の読み込みに失敗しました");
using var dstMean = new Mat();
using var dstGauss = new Mat();
// MeanC: 単純な局所平均を閾値に使用
Cv2.AdaptiveThreshold(src, dstMean, 255,
AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 15, 5);
// GaussianC: ガウシアン重み付き平均を閾値に使用(エッジが滑らか)
Cv2.AdaptiveThreshold(src, dstGauss, 255,
AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 15, 5);
Cv2.ImWrite("result_mean.png", dstMean);
Cv2.ImWrite("result_gauss.png", dstGauss);
Console.WriteLine("比較画像を保存しました");
例2: グレースケール変換 → 二値化 → 保存のパイプライン
カラー画像を受け取り、グレースケール変換してから適応的二値化まで一気に行う典型的なパイプラインです。
グレースケール変換の詳細は Cv2.CvtColor の使い方【OpenCV/C#】色空間をグレースケール・HSVに変換する を参照してください。
using OpenCvSharp;
using var color = Cv2.ImRead("input_color.png");
if (color.Empty()) throw new Exception("画像の読み込みに失敗しました");
using var gray = new Mat();
using var binary = new Mat();
// カラー → グレースケール
Cv2.CvtColor(color, gray, ColorConversionCodes.BGR2GRAY);
// 適応的二値化(ノイズを減らしたいので blockSize を大きめに設定)
Cv2.AdaptiveThreshold(gray, binary, 255,
AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 21, 8);
// ファイルに保存(詳細は Cv2.ImWrite の記事を参照)
Cv2.ImWrite("binary_output.png", binary);
Console.WriteLine("二値化完了");
ファイル保存の詳細は Cv2.ImWrite の使い方【OpenCV/C#】〜画像をファイルに保存する〜 を参照してください。
つまずきポイント
⚠️ 入力画像が8ビットグレースケールでないと例外が発生する
AdaptiveThreshold はグレースケール(CV_8UC1)専用です。カラー画像(CV_8UC3)をそのまま渡すと OpenCVException がスローされます。必ず Cv2.CvtColor でグレースケールに変換してから渡してください。
// NG: カラー画像を直接渡す → 例外
Cv2.AdaptiveThreshold(colorMat, dst, 255, ...);
// OK: グレースケールに変換してから渡す
Cv2.CvtColor(colorMat, gray, ColorConversionCodes.BGR2GRAY);
Cv2.AdaptiveThreshold(gray, dst, 255, ...);
⚠️ blockSize は奇数かつ3以上でなければならない
blockSize に偶数や1を渡すと実行時に例外が発生します。コンフィグ等から動的に値を渡す場合は、必ず if (blockSize % 2 == 0) blockSize++; のような補正を入れましょう。
// NG: blockSize = 10(偶数)→ OpenCVException
Cv2.AdaptiveThreshold(gray, dst, 255, ..., blockSize: 10, c: 2);
// OK: blockSize = 11(奇数)
Cv2.AdaptiveThreshold(gray, dst, 255, ..., blockSize: 11, c: 2);
⚠️ Mat の Dispose 漏れに注意
new Mat() で生成した dst を using で囲まずに放置すると、ネイティブヒープ側のメモリが解放されません。ループ内で繰り返し呼ぶ処理では特に顕著にリークします。using var dst = new Mat(); を必ず徹底してください。
関連する関数
- Cv2.Threshold — グローバル閾値での二値化。照明が均一な場合はこちらで十分です。
- Cv2.GaussianBlur — 二値化前にぼかしてノイズを除去すると結果が安定します。
- Cv2.CvtColor の使い方【OpenCV/C#】色空間をグレースケール・HSVに変換する — グレースケール変換はセットで使う必須関数です。
- Cv2.ImWrite の使い方【OpenCV/C#】〜画像をファイルに保存する〜 — 二値化結果の保存に使います。
まとめ
Cv2.AdaptiveThreshold は、照明ムラや影のある画像に対してグローバル閾値より圧倒的に安定した二値化を提供します。blockSize と c の2パラメータを現場画像で調整するだけで実用レベルに達することが多く、文書・基板・ラベル検査などで幅広く活用できます。入力は必ず8ビットグレースケールに変換してから渡すことを忘れずに。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。
→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

