サムネがコーヒーの記事は書きかけです。

ガウス分布で画像の平滑化処理(OpenCV)

ガウス分布

以下のような二次元ガウス分布を用いてカーネルを生成し、画像に平滑化処理を施してみたいと思います。

$$g(x,y,σ)=\frac{1}{2πσ^2}exp(-\frac{x^2+y^2}{2σ^2})$$

初めに、ガウス分布の良いところを実感するために、三次元空間に二次元ガウス分布をプロットしてみます。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize = (8, 8))
ax = fig.add_subplot(111, projection="3d")

ax.set_xlabel("x", size = 16)
ax.set_ylabel("y", size = 16)
ax.set_zlabel("g(x,y,σ)", size = 16)
pi = np.pi

x = np.linspace(-4,4,100)
y = np.linspace(-4,4,100)
X, Y = np.meshgrid(x, y)
s = 1.3
g = 1/(2*pi*s)*np.exp(-(X**2+Y**2)/(2*(s)**2))
ax.plot_surface(X, Y, g, cmap = "plasma_r")
fig.savefig('',dpi = 500)

以下が出力結果です。

このグラフから、注目画素から離れるにつれ重みの値が小さくなるということがわかります。

ガウスカーネルの生成

この性質を利用して、ガウスカーネルを生成します。

例えば上記の8近傍のカーネルでは

$$K = \begin{bmatrix}1/16&1/8&1/16 \\1/8&1/4&1/8 \\1/16&1/8&1/16 \\ \end{bmatrix}$$

となります。

k = np.array([[1/16, 1/8, 1/16],
                   [1/8, 1/4, 1/8],
                   [1/16, 1/8, 1/16]])

画像の平滑化

次は、ガウスカーネルを利用して画像を平滑化処理してみます。

imreadメソッドを利用してimg_rawに以下の画像を代入します。

import cv2
import numpy as np
img_raw = cv2.imread('image')

グレースケール化します。

img_gray = cv2.cvtColor(img_raw,cv2.COLOR_RGB2GRAY)
cv2.imwrite('gray.jpg',img_gray)

filter2Dメソッドを利用して、ガウシアンブラー処理を行います。入力画像をそのまま使うためddepthは-1です。

dst = cv2.filter2D(img_gray,-1,k)
cv2.imwrite('result.jpg',dst)

ぱっと見、グレースケールと変わらないですね。

カーネルサイズをもう少し上げてみますが、その前にcv2の便利なガウシアンブラーメソッドを紹介しておきます。

ガウシアンブラーメソッド

上記で示したようにガウス分布に従うカーネルを自力で生成することもできますが、カーネルサイズが大きくなってくると計算がめんどくさくなってくるため、カーネルサイズを指定するだけで勝手にガウシアンブラーをかけてくれるメソッドを使用します。

dst = cv2.GaussianBlur(img_gray, ksize=(25, 25), sigmaX=1.3)
cv2.imwrite('result_k=25.jpg',dst)

肉眼では、グレースケール画像とあまり見分けがつかないですね。

(σの値をあげることで平滑化処理の効果をあげることができます。)

次の記事でこの画像をフーリエ変換して高周波成分がどれくらい取り除けているかを確かめていきます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です