バイラテラルフィルタ

シェアする

  • このエントリーをはてなブックマークに追加
最近の記事
  • 7/6 【参考書籍】画像処理・機械学習プログラミング OpenCV 3対応
  • 6/20 【Python,matplotlib】動くグラフをAnimationGifに保存する方法
  • 6/17 シグモイド関数の微分
  • 6/15 シグモイド関数
  • 6/13 合成関数の微分
  • 6/12 WordPressで数式エディタ風に数式を入力したい
  • 6/11 PythonをVisual Studioでインストールする方法
  • 6/9 【Python】OpenCVをAnacondaでインストール(Windows編)
  • 6/6 【Python】Anacondaで複数バージョンの環境切り替え
  • 6/6 画像センシング展2017に出展します。
  • 6/1 【Office365】Web版Outlookのフォントサイズ変更
  • 6/1 【Anaconda】モジュールのアップデートでエラー発生
  • 6/1 【Anaconda】コマンドリストの表示
  • 5/29 Windows10パソコン購入
  • 5/24 Anacondaのアンインストール
  • 5/24 【Jupyter Notebook】新規プログラムの作成
  • 5/23 【Python】開発環境の構築
  • 5/23 Pythonはじめました
  • 4/6 【Office365】Web版Outlookのスレッド表示を解除する方法
  • 4/5 【Excel】フーリエ解析(FFT)
  • 3/20 Canny edge detection
  • 3/20 【Excel2016】分析ツールの表示
  • 3/5 【Visual Studio】黒い背景色を白に変更する方法
  • 2/8 【Windows10】拡張モニタに表示されたウィンドウを元に戻す
  • 2/7 複素数の計算
  • 1/18 【Excel】棒グラフの横軸の目盛を0始まりにする
  • 1/16 【Excel】フーリエ変換
  • 1/6 【OpenCV】疑似カラー(カラーマップ)
  • 11/8 【Visual Studio】検索結果のウィンドウ表示
  • 11/3 ニコン 一眼レフカメラ D5500レビュー
  • 10/26 カラーカメラはモノクロカメラを兼ねない
  • 9/6 (Free Soft)Animation GIF Builder
  • 8/30 【C#】タブの無いTabControlっぽいものを作る
  • 8/29 【OpenCvSharp】サンプルプログラムの公開
  • 8/28 【PowerPoint】部分的にカラーにする(セレクトカラー処理)
  • 8/27 【C#】引数の値渡し、参照渡し(ref, out)
  • 8/26 【Word/Excel】図形内に文字を挿入する
  • 8/25 【C#】NumericUpDownコントロール
  • 8/24 ニコン D3400 VS D5500 仕様比較
  • 8/22 【C#】MDIフォームにリサイズ可能なPanelを設置する
  • 8/20 【Visual Studio 2015】文字の色が変、かすむ
  • 8/20 【Visual Studio】行のコピー、切り取り、貼り付け
  • 8/20
  • 8/16
  • 7/7 標準偏差のよくある誤解
  • 6/17 ホーム
  • 6/15
  • 6/15
  • 6/15
  • 6/15

  • ガウシアンフィルタなどのフィルタでは、ノイズをできるだけ除去しようとすると、輪郭もボケてしまうという欠点がありました。
    この欠点を解決しようとした処理アルゴリズムがバイラテラルフィルタ(bilateral filter)です。

    バイラテラルフィルタは処理前の画像データの配列をf(i, j)、処理後の画像データの配列をg(i, j)とすると

    バイラテラルフィルタ

    となります。

    ただし、がカーネルのサイズ、σがガウシアンフィルタを制御、σが輝度差を制御しています。

    と言われても、何だか式が難しくて良く分かりません。

    でも、分母分子に出てくる最初のexpの部分はガウシアンフィルタで見たことがあるな~

    という事に気が付けば、突破口が開けます。

    2つ目のexpの部分が良く分からないので、とりあえず取っちゃってみて、

    バイラテラルフィルタ

    とすると、分母の部分がガウシアンフィルタと少し違うけど、Σの範囲が-W~Wなので、(2W+1)×(2W+1)のカーネルサイズのガウシアンフィルタになっています。

    結局、分母はカーネルの値の合計なので、やっぱりガウシアンフィルタそのものだという事に気が付きます。

    ここで、ガウシアンフィルタを使って、どうやれば輪郭をぼやかさず、ノイズだけを除去できるか?を考えると、カーネルの中心の輝度値と差の少ないところだけをガウシアンフィルタで平滑化すればいいのではないか?という発想が浮かびます。

    例えば次のような画像において、

    バイラテラルフィルタ

    四角で囲まれた部分を拡大し注目すると、5x5のガウシアンフィルタの場合、中心の輝度値に近い部分を重み「1」、輝度差が大きい部分は重みが「0」になるようにして、

    バイラテラルフィルタ

    一般的な5x5のガウシアンフィルタの係数↓、

    ガウシアンフィルタの係数

    に重みをかけると、それぞれのカーネルの値は

    バイラテラルフィルタ バイラテラルフィルタ
    カーネルの合計の169で割る カーネルの合計の209で割る

    となります。

    このようにして、場所、場所のカーネルの値を画像に合わせて変えて行くと、輪郭を残しつつノイズだけを除去できそうな感じがします。

    しかし、輪郭付近の重みは「1」にするべきか?「0」にするべきか?少し悩みます。

    そこで、カーネルの中心の輝度値との差に基づいて、重みを「0.3」や「0.8」のようなグレーゾーンを設けるために、輝度差を横軸にした正規分布を用いてみます。

    正規分布のグラフはこんな感じ↓

    正規分布

    になっていて、中心の0付近ほど値が大きく、外側(+方向、-方向)へ行くに従って値が小さくなります。

    この性質を使ってカーネルの中心の輝度値との差「f(i, j)- f(i + m, j + n) 」を横軸にとった正規分布の式は

    バイラテラルフィルタ

    となり、これを重みに使うと、「1」「0」だった重みが、輝度差が小さいと重みが大きく、輝度差が大きいと重みが小さくなるように、なだらかに変化します。

    この正規分布を重みとしたのが、まさにバイラテラルフィルタなのです。

    つまりバイラテラルフィルタは

    正規分布の重み付きガウシアンフィルタ

    なのです。

    ここで、最初に示したバイラテラルフィルタの式を見てみると、

    分子は(2W+1)×(2W+1)サイズのカーネルの範囲内の輝度値に、ガウシアンフィルタの係数をかけ、さらにカーネルの中心との輝度差を用いた正規分布の値を掛け合わせた値、

    分母はカーネルの合計値で、カーネルの合計値が1になるように調整しています。

    Wはカーネルの大きさ、σは通常のガウシアンフィルタの係数と同じ。

    σの値が、カーネルの中心の輝度値との差をどの程度許容するか?を制御している事が分かります。

    そのため、σの値を大きくしていくと、ただのガウシアンフィルタの処理に近づき、輪郭もぼやけてしまいます。逆にσの値を小さくし過ぎると、ノイズ除去効果が弱くなります。

    そこで、実際にはエッジを保持しつつノイズをできるだけ除去したい場合は、1回のバイラテラルフィルタでσ1、σの値を調整しようとするよりも、バイラテラルフィルタを何回か繰り返した方が効果的です。

    バイラテラルフィルタ バイラテラルフィルタ バイラテラルフィルタ
    原画 1回目 2回目
    バイラテラルフィルタ バイラテラルフィルタ バイラテラルフィルタ
    3回目 4回目 5回目

    このように、バイラテラルフィルタはガウシアンフィルタのカーネルに輝度差に基づいて重みを付けている訳ですが、この、×××に基づいて重みを付ける処理という考え方は、処理を安定させるポイントになったりします。

    例えばロバスト推定法なんかも近い感じ。

    画像処理アルゴリズムへ戻る

    コメント

    1. sygh より:

      g(i, j) の計算式中の分子、f(i+m, j+m) は f(i+m, j+n) ではないでしょうか?

      • akira より:

        遅くなりましたが、ご指摘ありがとうございます。
        記事を修正しました。

    2. Watanabe kazufumi より:

      非常に解りやすい解説で感謝致します。今度は是非trilateral filterの解説もお願いします

      • akira より:

        遅ればせながら、コメント頂きありがとうございます。
        trilateral filterはやった事が無いので、良く分かりませんが、Bilateralフィルタは、中心との距離をガウス関数に乗せて重みにしたもの(ガウシアンフィルタ)と、中心の輝度値との差をガウス関数に乗せて重みにしたものの2つの重みを使ったフィルタ処理なので、trilateral filterは3つの重みを使ったフィルタなんですよね?!きっと。
        trilateral filterを使う時が来たら、記事にしたいと思います。

    3. 長野宣道 より:

      本当に分かりやすいです。今まで漠然と理解していたものがクリアになってきました。お忙しい中、説明を追加して頂き本当に感謝します。どうか今後とも宜しくお願い致します。

      取り急ぎ、まずはお礼まで。