OpenCVの使い方11 ~ ぼかしフィルタ2
今回はOpenCVを用いて前回の画像にぼかし・ローパスフィルタ処理のノイズ画像に対しての適用例について紹介する。
以下のチュートリアル記事にある
画像の平滑化 — OpenCV-Python Tutorials 1 documentation
課題:ガウシアンノイズを足した劣化画像とごま塩ノイズを足した劣化画像に対して,箱型フィルタ,ガウシアンフィルタ,中央値フィルタ,バイラテラルフィルタを使って,ノイズレベルの変化に対して各フィルタによる結果画像がどのように変わるか試してください.
という課題をやってみることにする。
1. ガウシアンノイズを付加した画像作成
ガウシアンノイズ自体の生成はnp.random.norma(mu,sig,size)
を用いて正規分布を持ったノイズを生成する。muは平均値、sigは標準偏差、sizeは生成するノイズのサイズで画像データと同じにするにはnp.shape(src)=(256, 256, 3)
とする。以下で画像に付加するガウシアンノイズを生成することができる。
sig=70 noise=np.random.normal(0,sig,np.shape(src))
サンプル画像読み込み
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)
今回はサンプル画像は以下のマンドリルの画像を用い、画像データはsrc
に格納する。
生成されるノイズは実数であるため、元の画像データに付加したのち整数にするためにnp.floor()
を用いてまるめる。さらに画像データで0-255に収めるため、255を超える場合と0未満はそれぞれ255と0を埋める。さらにastype(np.uint8)
でアレイを型変換する。OpenCVでは入力形式が正しくないとエラーになる関数が多く、np.uint8
にしておくことがポイントになる。
imgnoi=src+np.floor(noise) #画像にノイズを付加 imgnoi[imgnoi>255]=255 # 255超える場合は255 imgnoi[imgnoi<0]=0 # 255超える場合は255 imgnoi2=imgnoi.astype(np.uint8) # 型変換 plt.imshow(imgnoi2)
ノイズを付加した画像は以下のようになる。
2. フィルタの適用例
生成したノイズ付加画像にフィルタを適用していく。まず平均化フィルタを適用する。
blur1 = cv2.blur(imgnoi2,(5,5)) blur2 = cv2.blur(imgnoi2,(10,10)) plt.figure(figsize=(10,5)) plt.subplot(1,2,1) plt.imshow(blur1) plt.subplot(1,2,2) plt.imshow(blur2)
左側は5x5ピクセル、右側は10x10ピクセルでの平均化で、10x10の方がぼけが強いがノイズは見えなくなっている。
次にガウシアンフィルタを適用する。(表示部分のコードは省略)
gauss1 = cv2.GaussianBlur(imgnoi2,(11,11),0) gauss2 = cv2.GaussianBlur(imgnoi2,(11,11),1,1)
左側は領域を11x11ピクセルで自動計算したもの、標準偏差を1に指定している。平均化と同様にぼけが強いとノイズは見えなくなる。
メディアンフィルタを適用する。
median1 = cv2.medianBlur(imgnoi2,5) median2 = cv2.medianBlur(imgnoi2,11)
平均化、ガウシアンと大きく異なるところはない。
最後にバイラテラルフィルタを適用する。
bilat = cv2.bilateralFilter(imgnoi2,25,75,75)
左のノイズ付加画像と比較して、右側のバイラテラルフィルタを適用すると、ノイズが少し改善して、他のフィルタと比較しても輪郭は保持されていることがわかる。
3. まとめ
今回は画像にノイズを付加する方法と、前回のぼかしフィルタを適用したときに効果について紹介した。