5.14. ガウス平滑化とエッジ¶
古典的なマシンビジョンで近傍ウィンドウが使われる用途は、2つの仕事が大半を占めます。ピクセル間のばらつきをきれいに平滑化することと、画像が急激に変化するエッジを見つけることです。ガウスフィルタは前者の標準的なツール、ラプラシアンベースの検出器は後者の標準的なツールです。そしてこの2つは組み合わさります。なぜなら、どのエッジ検出器も軽く平滑化された入力に対してのほうがうまく機能するからです。
5.14.1. ガウスフィルタ¶
gaussian() は mean() の中心重み付きのいとこです。どちらも各ピクセルの近傍にわたる平均を計算しますが、ガウスの重みは一様ではありません。近傍の中心に近いピクセルほど多く数えられ、近傍の端にあるピクセルほど少なく数えられ、その重みはこのフィルタの名前の由来であるおなじみのベルカーブに従います。
ベル型の重み付けこそが、ガウスフィルタをボックス平均よりも滑らかにするものです。平均フィルタリングは、オブジェクトのエッジで目に見えるアーティファクトを生じることがあります。重み付けの急なカットオフが、鋭い遷移部で小さなリンギングパターンを生じさせるのです。ガウスの滑らかに減衰する重みはそのリンギングを避け、「ぼかし」がこう見えるべきというものにより近い結果を生み出します。その代償は平均フィルタよりもピクセルあたりの計算が多いことですが、それほど劇的ではありません。ピクセルあたりのコストはバイラテラルフィルタよりもまだはるかに低いです。
img.gaussian(1) # 3x3 Gaussian -- a clean light blur
img.gaussian(2) # 5x5 Gaussian -- stronger smoothing
ガウス平滑化は、ほぼすべてのエッジ検出パイプラインの標準的な第1段階です。以下のエッジ検出器はいずれも高周波成分を増幅しますが、これにはアルゴリズムが実際には検出したくないセンサーノイズも含まれます。最初に軽いガウスを実行すると、実際のエッジをあまり鈍らせることなくそのノイズを抑制でき、エッジ検出器がスペックルではなく本物のエッジを見つけられるようになります。
5.14.2. アンシャープマスキング¶
画像をガウスでぼかしたコピーは、古典的なシャープ化にアンシャープマスク技法が使う素材です。フィルタで unsharp=True を設定すると、「ぼかした画像を生成する」から「ぼかした画像を元画像から減算し、その差分を元画像に加算し直す」へと切り替わります。その効果として、高周波のエッジが滑らかな内部に対して相対的に増幅されます。
img.gaussian(1, unsharp=True)
オプションの mul と add のパラメータは、アンシャープ結果の強度をスケーリングします。デフォルト(mul=1.0、add=0.0)は、センサーノイズを誇張しない控えめなシャープ化です。
5.14.3. ラプラシアンフィルタ¶
laplacian() は、画像の2階空間微分の離散近似を実行します。出力は、ピクセル値が急速に変化する箇所で大きく、一定または線形に変化している箇所ではゼロに近くなります。この結果を自然に読み解くとエッジ応答になります。画像が急速に変化するピクセルは明るくなり、滑らかな内部のピクセルは暗いままです。
img.laplacian(1) # 3x3 Laplacian -- edge response
gaussian と同じパラメータが利用できます。sharpen=True はシャープ化された画像を生成します(ラプラシアンが単独で返されるのではなく、元画像に加算し直されます)。mul と add は応答をスケーリングします。
エッジ検出以外の実践的な用途としてピント測定があります。ある領域にわたって平均したラプラシアン応答は、その領域がどれだけの高周波成分を持つかのおおまかな尺度になります。ピントが合ったフレームではその平均が高く、ぼやけたフレームでは低下します。フレーム間でラプラシアン応答を比較することは、より高価なコントラスト指標を必要とせずに「レンズのピントは合っているか」を問う安価な方法です。
5.14.4. find_edges メソッド¶
find_edges() は、単なるエッジ応答フィルタではなく、完全なエッジ検出パイプラインを実行します。グレースケール画像で動作し、結果は2値画像で、その非ゼロのピクセルは、入力にエッジと見なすべき種類の明るさの変化がある位置を示します。
このメソッドは、2つのアルゴリズムから選択する edge_type パラメータを取ります。
EDGE_SIMPLE はハイパスフィルタを実行し、しきい値を適用し、結果を返します。高速ですが、出力にはしきい値を超えるすべての明るさの変化が含まれ、アプリケーションがおそらく気にしないノイズやテクスチャも含まれます。クリーンな画像や、ノイズが後段のモルフォロジー処理でクリーンアップされるケースには妥当です。
EDGE_CANNY はCannyエッジ検出器、つまり古典的な多段アルゴリズムを実行します。明るさの勾配を計算し、勾配方向に沿って非極大の応答をすべて抑制し(これにより各エッジは1ピクセル幅になります)、ヒステリシスしきい値を適用します(これにより、ある箇所で強いエッジは、間で薄れる箇所でも追跡されます)。結果は、すべての古典的なエッジベースのアルゴリズムが望む種類の、きれいで細く連結したエッジピクセルの集合です。
threshold パラメータは2要素のタプル (low, high) です。EDGE_CANNY の場合、high の値はそれを超えればピクセルが確実にエッジとなるカットオフであり、low の値はそれを超えればピクセルが確実なエッジに連結している場合に限りエッジとなるカットオフです。EDGE_SIMPLE の場合、重要なのは high の値だけで、それを超えればピクセルがエッジと見なされる単一のカットオフです。デフォルトの (100, 200) は出発点であり、特定のシーンに合わせて調整する価値があります。
img.gaussian(1) # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))
Canny検出器は、エッジが重要なほぼすべてのアプリケーションでより良い選択です。より高速な EDGE_SIMPLE は、Cannyのコストが問題になり、そのヒステリシスによるノイズ除去が実際には必要ないケースのために覚えておく価値があります。
5.14.5. ガウスに対する適応的しきい値処理¶
統計フィルタ と同様に、gaussian() は適応的しきい値処理のための threshold=True / offset=N キーワードのペアを受け取ります。その動作は mean() の場合と同じです。各位置のガウス統計量が局所的なカットオフになり、ソースピクセルがその統計量にオフセットを加えた値と比較されて2値の結果が生成されます。
ガウスバリアントは、入力が十分にノイズが少ない場合、適応的しきい値処理にとって通常最もクリーンな選択です。重み付き平均は平均フィルタが生み出すよりも滑らかなカットオフを与え、鋭い照明の遷移部でのアーティファクトが少なくなります。