7  閾値処理

ここまで、処理の対象は「画像」――グレースケール値の2次元配列――でした。しかし、生産現場が本当に気にかけているのは「対象物」です。このチップのピンはどこにあるのか、この穴の直径はいくつか、このパネルに汚れはないか。画素の世界から対象物の世界へと踏み出す第一歩は、ほぼ常にセグメンテーション(segmentation)――対象物に属する画素と背景に属する画素を切り分けること――から始まります。そして、産業用ビジョンにおいて最も広く使われ、最も高速で、かつ最も過小評価されがちなセグメンテーションの手段こそが閾値処理(thresholding)です。グレースケール値 \(T\) を1つ選び、それより暗い(あるいは明るい)画素を前景に、残りを背景に割り当て、白黒の二値画像を出力します。

図 7.1 は典型的なシーンを示しています。バックライト(透過照明)下のパネルで、暗いテープのグリッドが明るい導光板に映えて鮮明なシルエットとなっています。自動閾値を1回適用するだけで、テープグリッドが白色の前景としてきれいに抽出されます――複雑なアルゴリズムは一切不要です。これはまさに チャプター 4 で述べた「適切な照明が、問題を1回の閾値処理にまで単純化できる」という約束が果たされた姿です。しかし、硬貨の裏側としてもう一面があります。閾値処理のグレースケール値への依存が直接的であるほど、照明変動に対する感度もまた激しくなります。本章では、定量化可能な一連の実験を通じて、この両面を明確にしていきます。

(a) バックライトパネルの原画像
(b) Otsu の閾値処理結果
図 7.1: 実画像の閾値処理。(a) バックライト(透過照明)下のパネル。暗いテープグリッドが明るい導光板の前に配置されている。(b) Otsu の自動閾値(自動的に \(T=125\) を選択)による二値化結果。\(T\) を下回るグレースケール値を持つテープと周辺の暗い領域が前景(白)としてマークされ、グリッド構造がきれいに抽出されている。

7.1 大域閾値とヒストグラム

大域閾値(global thresholding)は、閾値処理の最も素朴な形式です。画像全体で1つの閾値 \(T\) を共有します。暗い対象物の抽出を例にとると、

\[ g[n,m] = \begin{cases} 255, & f[n,m] \le T,\\[2pt] 0, & f[n,m] > T. \end{cases} \]

より一般的な形式はバンド閾値(band thresholding)です。区間 \([T_{\mathrm{low}}, T_{\mathrm{high}}]\) を与え、グレースケール値がそのバンド内に落ちる画素を前景とします。単一閾値は \(T_{\mathrm{low}}=0\)(あるいは \(T_{\mathrm{high}}=255\))の特殊ケースにすぎません。

\(T\) をどこに選ぶべきでしょうか?その答えはグレースケールヒストグラム(histogram)の中に隠されています。対象物と背景がそれぞれグレースケール値において一様で、コントラストが明瞭であれば、ヒストグラムには2つのピーク――前景と背景――が現れ、その間には谷ができます。これが双峰性ヒストグラム(bimodal histogram)です。\(T\) を谷の底に置けば、2つの集団はきれいに切り分けられます。本章の合成実験シーンは、まさにこのように設計されています。\(480\times360\) の画像上に、グレースケール値 160 の明るい背景と、48個の \(20\times20\) 画素の暗い正方形(グレースケール値 60、バックライト下のドットキャリブレーション標的を模す)を配置し、標準偏差 \(\sigma=6\) のガウシアンノイズを加算します(シード固定、再現可能)。正解の前景は合計 19200 画素です。図 7.2 (a) は均一照明のバージョン、図 7.2 (b) は同じシーンに水平方向の照明グラデーションを重ねたバージョンで、左端でゲイン \(\times 0.6\)、右端で \(\times 1.2\) とし、片側照明のむらをシミュレートしています。

(a) 均一照明シーン
(b) 水平グラデーション照明シーン
図 7.2: 合成テストシーン。(a) 均一照明:背景 160、正方形 60、\(\sigma=6\) のガウシアンノイズを加算。(b) 同じシーンに \(0.6\)(左)から \(1.2\)(右)へ変化する水平方向の照明ゲインを乗算したもの。左暗右明。

\(T\) は谷の底の中央に置くべきで、どちらかのピークの裾に寄せるべきではありません。ノイズ \(\sigma=6\) のとき、2つの集団はそれぞれほぼ \(\pm 3\sigma=\pm18\) レベルの広がりを持ちます。\(T\) をあるピークに近づけすぎると、その集団の「裾野」がそのピークを越えてしまいます。60 と 160 の間で \(T=110\) を選べば、両ピークまでそれぞれ 50 レベルの余裕が生まれ、十分なマージンとなります。

固定閾値 \(T=110\)(バンド \([0,110]\))は、均一シーン上で完璧と言える性能を示します。172800 画素中、誤分類 0 です(図 7.3 (a))。しかし、グラデーションシーンに移ると、同じ \(T\) は即座に破綻します(図 7.3 (b))。左端では背景のグレースケール値がゲインによって \(160\times0.6\approx96\) まで押し下げられ、110 を下回るため、画像左側の約 70 列の背景がまるごと閾値バンドに落ち込みます。誤分類は 23728 画素(13.73%)に達し、そのすべてが背景を前景と誤認する偽陽性(false positive)です。

(a) 固定 \(T=110\)、均一シーン
(b) 固定 \(T=110\)、グラデーションシーン
図 7.3: 固定閾値の成功と失敗。(a) 均一シーン:48個の正方形がすべてきれいに抽出され、誤分類 0。(b) グラデーションシーン:左端の背景のグレースケール値が 110 を下回り、領域全体が前景と誤認される。誤分類 23728 画素(13.73%、すべて偽陽性)。

この対照実験は、固定閾値の適用前提を明確に示しています。照明が安定していること、コントラストが制御されていること。この2つの条件はアルゴリズムが与えるものではなく、チャプター 4 の照明設計が与えるものです。バックライトによるシルエット、環境光対策の狭帯域フィルタ、フラットフィールドキャリブレーションは、すべて「1つの \(T\) を最後まで使い通す」ための条件を作るために存在します。条件が満たされるとき、固定閾値は最も速く、最も予測可能なソリューションです。条件が満たされないとき、どれほど入念に手調整した \(T\) も、次に来る照明の変動への頭金にすぎなくなります。

7.2 Otsu 自動閾値

手動で \(T\) を選ぶには、エンジニアがヒストグラムを見ながらパラメータを調整する必要があります。Otsu 法(Otsu’s method)はこのステップを自動化します:すべての候補閾値を走査し、「2つの集団を最もはっきり分離する」ものを選び出します。グレースケール値 \(i\) の正規化ヒストグラムを \(p_i\) とすると、閾値 \(T\) は画素を2つのクラスに分け、それぞれの割合と平均は次のようになります。

\[ \omega_0 = \sum_{i=0}^{T} p_i, \quad \omega_1 = \sum_{i=T+1}^{255} p_i, \quad \mu_0 = \frac{1}{\omega_0}\sum_{i=0}^{T} i\, p_i, \quad \mu_1 = \frac{1}{\omega_1}\sum_{i=T+1}^{255} i\, p_i. \]

Otsu の基準はクラス間分散(between-class variance)を最大化することです。

\[ \sigma_B^2(T) = \omega_0\,\omega_1\,(\mu_0-\mu_1)^2, \qquad T^\ast = \arg\max_T \sigma_B^2(T). \]

直感的に言うと、\((\mu_0-\mu_1)^2\) は「2つのクラスの中心が遠く離れていること」に報酬を与え、\(\omega_0\omega_1\) は「一方のクラスが大きくもう一方が小さい」という不均衡な分割にペナルティを与えます。チャプター 2 の分散分解により、全分散 \(\sigma^2 = \sigma_W^2 + \sigma_B^2\)(クラス内分散とクラス間分散の和)は \(T\) に依存しない定数であるため、クラス間分散の最大化はクラス内分散の最小化と等価になります——つまり、各クラスの内部をできるだけコンパクトにするということです。

均一シーンでは、Otsu は自動的に \(T=86\) を選択し、誤分類も同様に 0 となります。図 7.4 はその位置を示しています:双峰の間の谷底であり、手動調整の結果と同等に優れていますが、人的介入は一切不要です。照明が全体的に明るくなったり暗くなったりする場合(例えば光源の経年劣化)、2つのピークは一緒にシフトし、Otsu が選択する \(T\) も自動的に追従します——これが固定閾値に対する Otsu の真の優位性です。

図 7.4: 均一シーンのグレースケールヒストグラム。左側の小さなピークが前景の四角(中心約 60、19200 画素)、右側の大きなピークが背景(中心約 160)。縦線は Otsu が自動的に選択した閾値 \(T=86\) で、双峰の間の谷底にちょうど位置しています。

しかし、グラデーションシーンでの結果を見てください(図 7.5):Otsu は \(T=129\) を選択し、52475 画素(30.37%)を誤分類しています——固定閾値の 13.73% の2倍以上悪い結果です。理由は難しくありません:水平グラデーションが背景のグレースケール値を単一の 160 から \(96\) から \(192\) にまで広がる緩やかな傾斜に引き伸ばし、ヒストグラムの右側のピークは連続的な高原へと平坦化され、「双峰に挟まれた谷」という構造はもはや存在しません。Otsu は依然として忠実にクラス間分散の最大化を実行しますが、歪んだヒストグラム上では \(T^\ast=129\) は広げられた背景モードの内部に落ち込んでしまいます——背景の左側約3分の1のグレースケール値が 129 未満となり、その領域全体が誤警報となってしまうのです。

図 7.5: グラデーションシーンでの Otsu の失敗:自動的に \(T=129\) を選択し、画像左側の広範な背景が前景と誤判定され、52475 画素(30.37%)が誤分類されています。固定閾値よりも悪い結果です。

「自動」は「適応」を意味しません。Otsu が自動化するのは「\(T\) を選ぶという動作」であり、「空間変化への適応」ではありません——依然として単一の大域的 \(T\) を出力します。ヒストグラムは空間情報を完全に抹消した統計量です:照明グラデーションが破壊するのはまさに「同じクラスの画素は同じグレースケール値を共有する」という前提であり、どれほど賢いヒストグラムアルゴリズムでもそれを修復することはできません。

これが本章の最も重要な教育ポイントです:Otsu の暗黙の前提は、ヒストグラムが近似的に双峰性であることです。前提が成立する場合はパラメータ調整不要の強力なツールとなりますが、前提が崩れた場合は救済できないばかりか、「自動的に見える」がゆえにさらに惑わしやすくなります——エンジニアが生産ラインでの大量誤判定を経てようやく、自動選択された閾値が初日から間違った位置にあったことに気づくことが多いのです。

7.3 適応閾値

照明グラデーションの本質は、閾値が位置に応じて変化すべきということです。適応閾値処理(adaptive thresholding)はこれに正面から応えます——大域的な統計量を使う代わりに、各画素の周囲に \(K\times K\) の局所ウィンドウを開き、ウィンドウ内の統計量からその場で閾値を決定します。最も一般的な形式は「局所平均からオフセットを引く」ものです。

\[ T[n,m] = \mu_K[n,m] - \beta, \]

ここで \(\mu_K\) は局所平均、\(\beta\) は固定オフセットです。画素が自身の近傍の平均レベルより \(\beta\) 以上に暗い場合、(暗い)前景と判定されます。ウィンドウのスケール内では照明グラデーションはほぼ一定であり、画素値と局所平均を同時に押し上げるため、引き算により自動的にキャンセルされます——これこそが大域的手法には不可能な「空間的適応」です。オフセット \(\beta\) は平坦領域のノイズを抑制する役割を担います:\(\beta\) がない場合、均一な背景上の約半数の画素が当然ながら局所平均を下回り、無数の細かい斑点が発生してしまいます。

グラデーションシーンにおいて、局所適応閾値(\(K=81\)\(\beta=20\))の結果を 図 7.6 に示します:誤分類はわずか 41 画素(0.02%)——固定閾値の 23728 や Otsu の 52475 より3桁低く、最も暗い左端から最も明るい右端までの四角が平等に抽出されています。

図 7.6: グラデーションシーンでの局所適応閾値(\(K=81\)\(\beta=20\))の結果:誤分類はわずか 41 画素(0.02%)。照明グラデーションは局所統計により自動的にキャンセルされています。

ウィンドウは対象よりも明らかに大きくなければなりません。これは実測で得られた鉄則です:本実験でカーネルを 81 から 41 に縮小すると、四角の内部が「くり抜かれ」始めます。ウィンドウの大部分が \(20\) px の四角内部に入ると、局所平均自体が四角のグレースケール値に近づき、中心画素はもはや \(\mu_K-\beta\) より暗くなくなり、四角の内部は背景と判定されて輪郭の枠だけが残ります。対象が 20 px の場合、カーネル 81 でようやく安定します(SDK の局所平均は中心加重付きのため、有効ウィンドウサイズは公称サイズより小さくなります)。

その代償は2つの新しいパラメータの導入です。\(\beta\) の下限はノイズで決まり(約 \(3\sigma\) を超えるべきです。本例では \(\sigma=6\) なので \(\beta=20\) としています)、上限は対象のコントラストで決まります。\(K\) の規則は傍注の通りです:ウィンドウは対象サイズより大きくなければならず、さもなくば対象内部がくり抜かれてしまいます。同時に、ウィンドウは照明変化のスケールより小さくなければならず、さもなくば大域閾値に退化してしまいます。両端ともに余裕を残す必要があります。

最後に、本章と チャプター 4 のアプローチを対比してみましょう。照明むらに対して、私たちには等価な2つの対策があります:ルート1——まずシェーディング補正を行って背景を平坦化し、それから大域閾値を使う(チャプター 4 のアプローチ);ルート2——補正をスキップし、局所適応閾値を直接適用する(本章のアプローチ)。両者の数学的本質は実は同じであり——どちらも「背景の局所推定値を減算する」——違いはこのステップがグレースケール値領域で行われるか判定領域で行われるかだけです。エンジニアリング上のトレードオフは次の通りです:補正後のグレースケール画像が測定や OCR などの他のアルゴリズムにも使われる場合、ルート1を選べば1回の補正でパイプライン全体が恩恵を受けます;もし必要なのがこの1枚の二値画像だけなら、ルート2は1つの処理工程と中間画像のメモリ往復を省くことができます。

4つの実験結果を以下にまとめます(総画素数 172800、正解前景 19200):

方法 シーン 閾値 誤分類(画素) 誤分類率
固定 \(T=110\) 均一 110(手動) 0 0%
固定 \(T=110\) グラデーション 110(手動) 23728 13.73%
Otsu 均一 86(自動) 0 0%
Otsu グラデーション 129(自動) 52475 30.37%
適応 \(K=81\) グラデーション 画素ごと 41 0.02%

7.4 カラー画像の二値化

閾値処理の考え方はカラー画像に直接拡張できます。シングルチャネルの「バンド \([T_{\mathrm{low}}, T_{\mathrm{high}}]\)」を各チャネルに1つずつのバンドに置き換え、3つのバンドの共通部分を前景とします。RGB空間では、これは対象色を軸に平行な直方体で囲むことに相当します。RGBの限界は、3つのチャネルがすべて輝度情報と絡み合っている点にあります。照明が変化すると直方体では対象を囲めなくなります。実践的により堅牢な手法は、まずHSV空間に変換し、色相(hue)チャネルで色を選択し、彩度(saturation)チャネルで灰色や白色の領域を排除し、明度チャネルについては制限を緩めるか設けないことです。これにより、色のアイデンティティと照明強度が分離され、RGBの直方体よりも照明変動に対してはるかに堅牢になります。SciVisionのカラー二値化インターフェース(SDKマニュアル 5.3節)も、このチャネルごとのバンド閾値方式で動作します。本章の付随プロジェクトはグレースケールの実験に焦点を当てており、カラー二値化の定量的な比較は含まれていないため、ここでは原理の説明のみを行います。

7.5 SciVisionでの実装

本章の閾値アルゴリズムは SCIMV::SciSvThreshold クラスで提供されます。固定(手動)閾値の呼び出しは付随プロジェクトと一致します:

SCIMV::SciSvThreshold th;
SciImage dst;
SciROI roi;
SciPoint tl(0, 0), br(W, H);   // GenRect1 右下角为排他端点:全图须传 (W,H)
roi.GenRect1(tl, br);

// 带阈值 [0,110]:灰度落在带内的像素在输出中为白(255)
long rc = th.ManualThreshold(img, roi, 0, 110, SCI_THRESHOLD_TYPE_WHITE, 0, &dst);

ManualThreshold(src, roi, lower, upper, lightOrDark, checked, dst) において、lower/upper は閾値バンドの下限と上限です。lightOrDark というパラメータ名は、「明るい対象を抽出するか暗い対象を抽出するか」を選択するものだと誤解されやすいですが、実測の結果、そうではありません。出力の色付けを制御するものであり、対象の選択を制御するものではありません。0(SCI_THRESHOLD_TYPE_WHITE)を渡すと、バンド内の画素は出力において白(255)になります。バンド \([0,110]\) で暗い対象を抽出する際は、AutoThreshold の出力規約(前景は白)と一致させるために、必ず0を渡して対象を出力内で255にする必要があります。誤った値を渡すと二値画像の白黒が反転し、下流の チャプター 23 の連結成分統計が背景を対象としてカウントしてしまいます。

自動閾値(Otsuおよび局所適応)は1つのインターフェースを共有します:

int t = -1;
// autoThresholdType=1:Otsu,自动选出的阈值经 t 返回(kernelSize/belta 不起作用)
rc = th.AutoThreshold(img, roi, SCI_THRESHOLD_TYPE_BLACK, 1, 3, 5, 0, &t, &dst);

// autoThresholdType=6:局部自适应,kernelSize=81 为窗口边长,belta=20 为偏置
rc = th.AutoThreshold(img, roi, SCI_THRESHOLD_TYPE_BLACK, 6, 81, 20, 0, &t, &dst);
パラメータ 意味 本章での値と説明
lightOrDark 対象の極性 SCI_THRESHOLD_TYPE_BLACK(暗い対象を抽出)
autoThresholdType アルゴリズムの選択 1 = Otsu、6 = 局所適応
kernelSize 局所ウィンドウの辺の長さ \(K\) 81(20 pxの対象より明らかに大きい必要がある、41では四角形がくり抜かれる)
belta 局所オフセット \(\beta\) 20(およそ \(3\sigma\) のノイズの広がりより大きい必要がある)
value 出力:自動選択された閾値 Otsuの場合、選択された \(T\) を返す(一様シーンでは86、グラデーションシーンでは129)

2つのエンジニアリング上の詳細を特筆しておく価値があります。1つ目は前述の lightOrDark のセマンティクスです。2つ目は、SciROI::GenRect1右下角を排他的な端点として扱うことです。画像全体のROIには \((W,H)\) を渡す必要があります。「最後の画素の座標」という直感に従って \((W-1,H-1)\) を渡すと、最後の行と最後の列、合計 \(W+H-1=839\) 個の画素が処理対象から除外され、元のグレースケール値が保持されます。二値画像上では目立たない「漏れのある境界枠」ですが、画素ごとの検証を台無しにするには十分です。本章のすべての実験画像を生成する完全なプロジェクトは code/thresholding/ にあります。

産業事例:バックライト測定における閾値ドリフト

あるバックライトによる寸法測定ステーションでは、当初、固定閾値を使用してワークのシルエットを抽出していました。数ヶ月の運用後、測定寸法に系統的なゆっくりとしたドリフトが現れました。調査の結果、バックライトのLEDの経年劣化に起因することが判明しました。月ごとに輝度が低下し、固定閾値で切り出される輪郭がそれに伴って外側に拡大し、寸法が少しずつ「大きく測定」されていたのです。Otsuに切り替えた後、問題は解消しました。光強度が全体として減衰する際、ヒストグラムの両方のピークが一緒にシフトし、自動閾値がそれに追従するため、測定は安定しました。しかし、ある日、生産ラインで突然バッチ不良が発生しました。導光板の局所的な汚れが背景ピークから長い裾を引き出し、ヒストグラムの双峰構造が歪み、Otsuが選択した閾値が背景のモードに突っ込み、バッチ全体のワークの輪郭がすべて誤りました。まさに本章のグラデーション実験の現場での再現です。最終的な解決策は、Otsuに双峰性チェックを追加することでした。毎回のセグメンテーションの前に、ヒストグラムの2つのピーク間の距離と谷の深さを確認し、指標が許容範囲を超えた場合はアラームを出して判定を停止します。「自動」には「自己チェック」を組み合わせて初めて、生産ラインでの無人運用が可能になります。

7.6 まとめ

  • 閾値処理は画素から対象への第一歩です。1つ(または1つのバンド)のグレースケール閾値が画像を前景と背景の二値画像に切り分けます。その上限は照明によって決まります。照明が安定し、コントラストが制御可能な場合、固定閾値が最速で最も予測可能です(一様シーンでの誤分類は0)。照明にグラデーションが生じた瞬間、同じ閾値は直ちに機能しなくなります(13.73%)。
  • Otsuはクラス間分散の最大化 \(\sigma_B^2(T)=\omega_0\omega_1(\mu_0-\mu_1)^2\) により閾値を自動選択し、照明の全体的な明暗の変化に追従できます。しかし、その暗黙の前提はヒストグラムが近似的に双峰性であることです。前提が崩れると、手動調整よりも悪くなる可能性があります(グラデーションシーンで30.37%対13.73%)。「自動」は「適応」を意味しません。
  • 適応閾値 \(T[n,m]=\mu_K[n,m]-\beta\) は局所統計を用いて照明のグラデーションを打ち消します(誤分類は0.02%に低下)。ウィンドウ \(K\) は対象のサイズより明らかに大きい必要があります。そうでないと、対象の内部がくり抜かれます(カーネル41は失敗、81で安定)。\(\beta\) はノイズの広がりより大きい必要があります。
  • 照明の不均一に対する等価な対策は2つあります。シェーディング補正を行ってから大域閾値を適用する方法(チャプター 4)、または直接局所適応閾値を適用する方法(本章)です。中間のグレースケール画像に他の用途がある場合は前者を選び、二値画像だけが必要な場合は後者を選びます。
  • 二値画像は中間点であり、終点ではありません。残存する孤立したノイズや粗いエッジは チャプター 8 のモルフォロジーによるクリーンアップに委ねられ、前景画素から対象への集約とその計測は チャプター 23 のテーマです。

本章のOtsu法は、1979年の原著論文 (Otsu 1979) に基づいています。さまざまな閾値処理手法の体系的な比較と定量的な評価については、SezginとSankurのサーベイ (Sezgin と Sankur 2004) を参照してください。デジタル画像処理の全体的なフレームワークにおける閾値処理の位置づけについては、GonzalezとWoodsの教科書 (Gonzalez と Woods 2018) を参照してください。閾値処理と領域抽出アルゴリズムとの体系的なつながりについては、Stegerらの著書 (Steger, Ulrich, と Wiedemann 2018) をさらに読むことをお勧めします。