【画像処理基礎】ぼかしの基本!ガウシアンフィルタって何?

写真の主役を引き立たせるために背景をぼかしたり、プライバシー保護のため写真の顔をぼかしたりしますよね?

Photoshopなどの画像処理ソフトで画像をぼかそうとすると、種類がたくさんあって何を使ったらいいものか…。

本記事では、ぼかしの基本であるボックスフィルタガウシアンフィルタについて解説します。また、PythonとOpenCVで実際に写真をぼかす実践をします。この記事を読めば、画像をぼかしたかったら、悩まずガウシアンフィルタを選択すれば無難なことが分かります。

もう、ぼかしで悩むことから脱却しましょう!

この記事はこんな人におすすめ!

  • 画像処理を学んでいる初心者
  • ぼかしの技術を理解したい人
  • プログラミングで画像処理を実践したい人
目次

空間フィルタリングとは

概念

ぼかしを学ぶ前に空間フィルタリングを理解する必要があります。フィルタを直訳すると、ろ過器やこし器などです。画像処理では、画像をこの空間フィルタで処理することで様々な画像に変換します。空間フィルタには、ぼかすためのフィルタ、エッジを抽出するためのフィルタ、ノイズを除去するためのフィルタなどがあります。

空間フィルタの概念は、コーヒーの抽出で例えることができます。コーヒーは、コーヒーの粉をコーヒーフィルタに入れ、お湯を注ぐと作ることができますよね。澄んだお湯がコーヒーフィルタを介すと黒く濁ったコーヒーになる。空間フィルタリングも同様なイメージです。入力画像は、お湯です。空間フィルタリングは、コーヒーフィルタです。コーヒーの粉は、ぼかしフィルタなどフィルタの種類です。出力画像は、コーヒーです。入力画像をぼかしフィルタで処理すると、出力画像は入力画像がぼけた結果になります。

空間フィルタは、線形フィルタと非線形フィルタに分けられます。ボックスフィルタ、ガウシアンフィルタは線形フィルタのため、ここでは線形フィルタについて解説していきます。

線形フィルタの数式

線形フィルタは、入力画像を\(f(i,j)\)、出力画像を\(g(i,j)\)とするとき、以下の式により計算されます。

$$g(i,j)=\sum_{n=-W}^{W}\sum_{m=-W}^{W}f(i+m,j+n)h(m,n)$$

\(h(m,n)\)はフィルタの係数を表す配列であり、フィルタの種類によってこの配列は変わってきます。ボックスフィルタ、ガウシアンフィルタの係数は次章で詳しく説明します。

フィルタの大きさは、\((2W+1)\times (2W+1)\)です。\(W=1\)の場合、\(3\times 3\)行列、\(W=2\)の場合、\(5\times 5\)行列となります。

数式見てもイメージしづらいですよね…。

計算例

そこで数式に具体的な数値を代入し、イメージしやすくしましょう。下図は3×3フィルタの計算例です。

入力画像の(i,j)座標の画素は「10」でしたが、フィルタを通すと(i,j)座標の画素は「7」となります。

3×3フィルタの場合は、入力画像のある画素に対して、上下左右斜めの8画素が影響し出力画素となっていますよね。これが空間フィルタリングと呼ばれる理由です。

空間フィルタリングの知識は身に付いたと思いますので、画像をぼかすためのボックスフィルタ、ガウシアンフィルタについて解説していきます。

ボックスフィルタとは

ボックスフィルタは、非常に簡単なぼかし(平滑化)フィルタです。フィルタの範囲を平均化するのみです。3×3フィルタの場合は、3×3=9画素をフィルタしますので、各フィルタ係数は9分の1となります。同様に5×5フィルタの場合は、各フィルタ係数は25分の1となります。

ガウシアンフィルタとは

ガウシアンフィルタは、フィルタ係数がガウス分布となっているものです。

ガウス分布?

ガウス分布とは、正規分布とも呼ばれ、確率論や統計学で用いられる連続的な変数に関する確率分布の一つです。平均値と最頻値と中央値が一致し、これを中心に左右対称な山なりの分布です。自然界の多くの事象がガウス分布に従うと言われています。

1次元のガウス分布は以下式で表されます。σは標準偏差です。

$$h_g (x) = \frac{1}{\sqrt{2\pi}\sigma}\exp(-\frac{x^2}{2\sigma^2})$$

グラフにすると下図です。

σが小さいと尖った山となり、周辺画素の影響は小さくなります。σが大きくなるにつれて、山は平坦となり、周辺画素の影響が大きくなります。ぼかしを強くしたいならσを大きくすればよいことが分かります。

画像は2次元ですので、2次元ガウス分布が必要です。2次元ガウス分布は以下式で表されます。

$$h_g(x) = \frac{1}{2\pi\sigma^2}\exp(-\frac{x^2+y^2}{2\sigma^2})$$

σ=2を代入してグラフにするとこんな感じ。

この式からNxNフィルタ係数行列を作れば、ガウシアンフィルタの出来上がりです。

OpenCVを用いたぼかし処理

PythonとOpenCVライブラリを用いれば、簡単にボックスフィルタとガウシアンフィルタで画像をぼかすことが出来ます。

ボックスフィルタのPythonプログラム

まず、ボックスフィルタのサンプルプログラムです。

import cv2 as cv

def concat_tile(im_list_2d):
    return cv.vconcat([cv.hconcat(im_list_h) for im_list_h in im_list_2d])

img = cv.imread("sample.jpg") # 写真の読み込み
img = cv.resize(img, None, fx=0.5, fy=0.5) # 写真サイズを2分の1

img_blur3 = cv.blur(img, (3, 3)) # 3×3のボックスフィルタ
img_blur5 = cv.blur(img, (5, 5)) # 5×5のボックスフィルタ
img_blur7 = cv.blur(img, (7, 7)) # 7x7のボックスフィルタ

imgs = concat_tile([[img, img_blur3], [img_blur5, img_blur7]])

cv.imshow("img", imgs)
cv.imwrite("output.jpg", imgs)

if cv.waitKey(0) & 0xFF == ord('q'):
    cv.destroyAllWindows()

左上が元画像。右上、左下、右下がそれぞれ3×3、5×5、7×7のボックスフィルタを適用した画像です。

フィルタサイズが大きくなるほど、ぼかしが強くなっていくことが分かります。

blur関数を用いることで入力画像にボックスフィルタを簡単に適用することができます。
cv.blur(img, (N, N)) # N×Nのボックスフィルタ

第1引数に入力画像、第2引数にフィルタサイズを設定します。

ガウシアンフィルタのPythonプログラム

次にガウシアンフィルタのサンプルプログラムです。

import cv2 as cv

def concat_tile(im_list_2d):
    return cv.vconcat([cv.hconcat(im_list_h) for im_list_h in im_list_2d])

img = cv.imread("sample.jpg") # 写真の読み込み
img = cv.resize(img, None, fx=0.5, fy=0.5) # 写真サイズを2分の1

img_gauss1 = cv.GaussianBlur(img, (0, 0), 1) # σ=1のガウシアンフィルタ
img_gauss2 = cv.GaussianBlur(img, (0, 0), 2) # σ=2のガウシアンフィルタ
img_gauss3 = cv.GaussianBlur(img, (0, 0), 3) # σ=3のガウシアンフィルタ

imgs = concat_tile([[img, img_gauss1], [img_gauss2, img_gauss3]])

cv.imshow("img", imgs)
cv.imwrite("output.jpg", imgs)

if cv.waitKey(0) & 0xFF == ord('q'):
    cv.destroyAllWindows()

左上が元画像。右上、左下、右下がそれぞれσ=1、σ=2、σ=3のガウシアンフィルタを適用した画像です。

σを大きくすると、ぼかしが強くなります。

GaussianBlur関数を用いることで入力画像にガウシアンフィルタを簡単に適用することができます。
cv.GaussianBlur(img, (0, 0), N) # σ=Nのガウシアンフィルタ

第1引数に入力画像、第2引数にフィルタサイズ、第3引数にσを設定します。

ここでフィルタサイズが0?と思われるでしょう。

openCVでは、フィルタサイズを0に設定するとσに応じてフィルタサイズが自動設定されます。

フィルタサイズ設定に困ったら、σだけ設定すればよいです。

ボックスフィルタとガウシアンフィルタを比べてみると、ガウシアンフィルタの方がぼかしが自然かと思われます。画像をぼかしたかったら、ガウシアンフィルタを選んでおけば間違いないです。

まとめ

本記事では、ぼかしの基本であるボックスフィルタ、ガウシアンフィルタについて解説しました。また、PythonとOpenCVで実際に写真をぼかす実践をしました。

画像をぼかしたかったら、悩まずガウシアンフィルタを選択すれば無難なことが分かりましたね。

これで、写真の主役を引き立たせるために背景をぼかしたり、プライバシー保護のため写真の顔をぼかしたりが出来ると思います。

この記事が画像処理を学ぶ皆さんのためになれば幸いです。最後まで読んで頂きありがとうございました!

独学が大変な方は、書籍やスクールを活用するのも手です。私も活用しているものを載せておきますので参考にして下さい。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

大学で機械工学を学んだ後、製造業で働く40代の会社員です。
IT系、電気系を学んでこなかった機械系人間が、ゲーム制作、電子工作に奮闘してます。
極力低コストでものづくりを楽しむのがモットー。

目次