概要
バイラテラルフィルタについて解説し、OpenCV の cv2.bilateralFilter でバイラテラルフィルタを適用する方法を紹介します。
バイラテラルフィルタ
バイラテラルフィルタとは、エッジを保存しつつ、平均化を行うように設計された次で紹介するフィルタです。
ガウシアンフィルタの欠点
分散を σ、カーネルサイズを n としたガウシアンフィルタの重みは以下のようになっていました。
f(x,y)=2πσ21exp(−2σ2x2+y2)dst(x,y)=i=0∑n–1j=0∑n–1f(x+i,y+j)src(x+i,y+j)ガウシアンフィルタは対象の画素値をより強調するように平均化を行うフィルタですが、以下の画像のようにエッジも平均化されてしまうため、物体の輪郭がぼやけた画像になります。
ガウシアンフィルタの適用結果
画像のエッジとは輝度値が大きく変わる部分です。
エッジ
ガウシアンフィルタでエッジがぼやけてしまう原因は対象画素と輝度値の差が大きい画素まで考慮してしまうためです。
バイラテラルフィルタの変更点
対象画素と輝度値の差が大きい画素は小さい重み付けになるようにガウシアンフィルタの重みを以下のように変更します。
f(x,y,x’,y’)=exp(−2σ2x’2+y’2)exp(−2σ2((src(x,y)–src(x’,y’))2)新たに追加された項の (src(x,y)–src(x’,y’))2 は対象の画素値 src(x,y) と周辺の画素値 src(x’,y’) との距離の2乗です。これを d としたとき、
exp(−2σ2d2) のグラフを描画すると以下のようになります。
距離 d=0 のとき 1 をとり、差が大きくなるにつれ、指数関数的に 0 に近づいていきます。この仕組みにより対象画素と輝度値の差が大きい画素について、小さな重みがつくようになります。
上の重み関数 f(x,y,x’,y’) を使って、出力値は次のように計算されます。
dst(x,y)=c1i=0∑n–1j=0∑n–1f(x,y,x+i,y+j)src(x+i,y+j)ただし、c は c1∑i=0n–1∑j=0n–1f(x,y,x+i,y+j)=1 とするための正則化項で
c=j=0∑n–1f(x,y,x+i,y+j)
cv2.bilateralFilter()
でバイラテラルフィルタを適用できます。
引数の sigmaColor
、sigmaSpace
は以下に対応します。
f(x,y,x’,y’)=exp(−2σspace2x’2+y’2)exp(−2σcolor2((src(x,y)–src(x’,y’))2)
sample.jpg
エッジは保持したまま、平均化ができていることが確認できます。
コメント