まえがき
すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応 (日本語) 単行本 –の3章4項でガウシアンフィルターなるものに遭遇。全くの初見だったので色々と調べると、
- 画像は高周波と低周波に分離可能
- 高周波は変化が激しく、低周波は変化が少ない。自然の画像だと低周波の部分が多くなる
- 一般に画像処理を行う際には、前処理として平滑化を行い、高周波の部分を少なくする(エッジやノイズを低減する)
- 平滑化を行うことで画像の本質である低周波の部分をなるだけ損なうことなく、処理をしやすくする(???)
- 平滑化のために使うフィルタにはいくつか種類があり、そのうちの1つがガウシアンフィルター
- ガウシアンフィルターは一律に平滑化するのではなく、注目画素からの距離に応じて重みを変えることで、自然な平滑化が実現できる(??)
らしいです。まあとにかく輪郭検出の際にやるルーティーンのようなものとのことでした。
本編
ガウシアンフィルターは、以下の式に基づいて画像の平滑化を実行します。
$$f(x, y) = \frac{1}{2\pi\sigma^2}exp\left(-\frac{x^2 + y^2}{2 \sigma^2}\right)$$
$x,y$は注目画素からの距離、$\sigma$は標準偏差であり、$\sigma$を大きくするほどぼかしがきつくなるようです。
ここでシンプルに疑問に思ったのが、「そもそもこの関数は何者なのか?」ということです。最近は4次元以上の関数やベクトル?にかち合うタイミングも多く、図示ができずなかなかに理解に苦しんでいるのですが、「これだったら3次元でいけるじゃん!」ってことで、matplotlibを使ってグラフにしてみました。
コード
$x,y,\sigma$から値を返すガウス関数の関数を用意し、np.arrangeで指定した空間上にメッシュグリッドとして表示しています。3次元グラフをシンプルなコードでサクサクと描けてしまうmatplotlib君は本当に優秀です。
import math
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
def gaussian_func(x, y, sigma):
exponent = - (x ** 2 + y ** 2) / (2 * pow(sigma, 2))
denominator = 2 * math.pi * pow(sigma, 2)
return pow(math.e, exponent) / denominator
x = np.arange(-3.0, 3.0, 0.001)
y = np.arange(-3.0, 3.0, 0.001)
X, Y = np.meshgrid(x, y)
Z = gaussian_func(X, Y, 1)
fig = plt.figure(figsize=(10, 10))
ax = Axes3D(fig)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("f(x, y)")
ax.plot_wireframe(X, Y, Z)
plt.savefig("gaussian.jpg")
plt.show()
出力画像
今回は$(x, y) = (0, 0)$を中心としてあるため、そこから外側に向かってなだらかに下っていく形になりました。実際はこの中心が注目画素であり、そこから距離が離れるにつれてぼかしが強く、元の情報が損なわれていくのですね。実際の計算としては画素とガウシアン関数の値の畳み込み和らしいです。
あとがき
多分2割くらいしかわかっていないと思うんですが、少なくともガウシアンフィルターが何をやっているのか朧気に掴むことはできました。
集合知に感謝。