つれづれなる備忘録

日々の発見をあるがままに綴る

OpenCVの使い方12 ~ ぼかしフィルタ3

 今回はOpenCVを用いてカスタムのぼかしフィルタを作成して適用する方法について紹介する。

atatat.hatenablog.com

1. サンプル画像の生成

サンプル画像読み込み

import cv2
import numpy as np
from matplotlib import pyplot as plt
from google.colab import files
uploaded_file = files.upload()
uploaded_file_name = next(iter(uploaded_file))
orig = cv2.imread(uploaded_file_name)
src = cv2.cvtColor(orig, cv2.COLOR_BGR2RGB)
plt.imshow(src)

今回はサンプル画像は以下のPepperの画像を用い、画像データはsrcに格納する。

"Pepperの画像"
Pepperの画像

前回と同様の方法でノイズを付加する。

sig=70
noise=np.random.normal(0,sig,np.shape(src))
imgnoi=src+np.floor(noise)
imgnoi[imgnoi>255]=255
imgnoi[imgnoi<0]=0
imgnoi2=imgnoi.astype(np.uint8)
plt.imshow(imgnoi2)

ノイズを付加した画像imgnoiは以下のようになる。

"ノイズ付加画像"
ノイズ付加画像

2. カスタムフィルタの作成・適用

 要素がすべて1である行列を用いることで平均化フィルタと同じ効果のフィルタが得られる。例えば5x5で要素1の行列はcv2.blur(src,(5,5))と同じになる。 行列を生成してフィルタとして画像に適用するにはcv2.filter2D(imgnoi2,-1,kernel3)を用いる。-1は出力画像の画素深さを入力画像と同じに指定している。

kernel3 = np.ones((5,5),np.float32)/25
myblur = cv2.filter2D(imgnoi2,-1,kernel3)
plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
plt.imshow(imgnoi2)
plt.subplot(1,2,2)
plt.imshow(myblur)

左側は元の画像、右側は行列を用いたフィルタを適用した画像で、ぼかし処理になっていることがわかる。

"カスタムフィルタ"
カスタムフィルタ

次に重みを付ける行列を生成し、重み付き平均化フィルタを適用する方法について紹介する。行列のサイズは同じだが、中心部に大きな値を設定する。 np.ones(5,5)で5x5で要素1の行列に3x3で要素2の行列をスライスを用いて上書きし、中心アドレス(2,2)の値を3に設定する。最後に行列の総和が1になるようにnp.sum(kernel)で割れば重み付き平均化を実行する行列となる。

kernel = np.ones((5,5),np.float32)
kernel2=np.ones((3,3),np.float32)*2
kernel[1:4,1:4]=kernel2
kernel[2,2]=3
kernel
>array([[1., 1., 1., 1., 1.],
       [1., 2., 2., 2., 1.],
       [1., 2., 3., 2., 1.],
       [1., 2., 2., 2., 1.],
       [1., 1., 1., 1., 1.]], dtype=float32)

行列をフィルタとして適用するには、上と同様にcv2.filter2D()を用いる

kernel=kernel/np.sum(kernel)
myblur = cv2.filter2D(imgnoi2,-1,kernel)
plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
plt.imshow(imgnoi2)
plt.subplot(1,2,2)
plt.imshow(myblur)

左側は元の画像、右側は重み付き行列を用いたフィルタを適用した画像だが、単純平均とあまり大きな差はない。

カスタム重み付きフィルタ
カスタム重み付きフィルタ

直接行列をフィルタとして用いる方法の他にcv2.getGaussianKernel()を用いてガウシアンフィルタを生成する方法がある。 cv2.getGaussianKernel(size,sigma)はサイズ:sizeと標準偏差sigmaの1次元配列を生成し、cv2.sepFilter2D(imgnoi2,10,kernelg,kernelg)を用いて生成したガウシアンフィルタのカーネルを2次元画像に適用する。 なおXY方向ともにkernelgを適用するため、kernelgを2つ並べている。

kernelg=cv2.getGaussianKernel(11,10)
dst=cv2.sepFilter2D(imgnoi2,-1,kernelg,kernelg)
plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
plt.imshow(imgnoi2)
plt.subplot(1,2,2)
plt.imshow(dst)

左は元の画像、右はcv2.getGaussianKernel()を用いて生成したガウシアンフィルタを適用した画像になる。

"カスタムガウシアンフィルタ"
カスタムガウシアンフィルタ

3. まとめ

 今回はカスタムのぼかしフィルタの作成・適用方法について紹介した。