ガウシアンノイズと画像へのノイズ付与(Python+OpenCV)

信号処理で著名なノイズとして「ガウシアンノイズ」があります。
本日はこのガウシアンノイズに関する理解を深めると共に、実応用として画像の輝度値へのガウシアンノイズの付与を行うプログラムを作成してみたいと思います。

ガウシアンノイズ(Gaussian Noise)とは

ガウシアンノイズとは、正規分布(ガウス分布)と等しい確率密度関数を持つノイズのことです。

例えば画像処理などの分野では、カメラなどで画像を撮影した際にセンサの測定誤差で、画像にノイズが混入することがありますが、このノイズをモデル化する手段としてガウシアンノイズが使われることがあります。

平均がμ、標準偏差がσの場合、以下の確率密度関数に従う分布となります。

上記の数式だけではイメージが沸きにくいかもしれませんが、以下のような分布を取る確率分布となります。

よくある例としては偏差値で、偏差値は平均μ=50で、σ=10と設定しています。

すなわち、上記のグラフで言えば

偏差値40(μ-σ)~60(μ+σ)に68%の人が、
偏差値30(μ-2σ)~70(μ+2σ)に95%の人が、
偏差値20(μ-3σ)~80(μ+3σ)に99.7%の人が、

存在するような確率分布ということになります。

そして、ガウシアンノイズはこの確率分布に従うノイズです。

σ=10のガウシアンノイズ(平均0)の場合、多くの信号値に-10~10程度のノイズが付与されることになります。逆に30や50などの3σや5σに対応されるノイズ値が振られることは確率的にほとんどありません。

実際に、画像にガウシアンノイズを付与するプログラムを以下で見ていきましょう。PythonとOpenCVを使って書いていきたいと思います。

画像へのガウシアンノイズ付与プログラム(Python+OpenCV)

ソースコード全体

import numpy as np
import matplotlib.pyplot as plt
import cv2
# Loading image data (GreyScale)
image = cv2.imread('data/lenna.png', cv2.IMREAD_GRAYSCALE)
# Generating noise
mean = 0;
sigma = 10;
noise = np.random.normal(0, sigma, np.shape(image))
# Noise is added to image
image = image + noise
# Pixel value adjustment [0,255]
image[image > 255] = 255
image[image < 0] = 0
# Saving image
output_image = image.astype(np.uint8) # Float -> Uint
cv2.imwrite('output.jpg',output_image)
# Creating noise histogram
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.hist(noise, bins=120, Color = "b", rwidth=1)
ax.set_title('Noise histgram $\mu=' + str(mean) + ',\ \sigma=' + str(sigma) +'$')
ax.set_xlabel('noise signal value')
ax.set_ylabel('pixel count')
fig.savefig("noise_histgram.jpg")

入力データとしては、以下の画像を用いました。仕様としては、カラー画像を入力した場合でも、グレースケール(単色)に変換した上で、輝度値にガウシアンノイズを付与することが可能です。

プログラム中のsigmaを変更することで、ノイズの大小を変更することが可能です。

実行結果

1) sigma=10の場合(上:ノイズの値のヒストグラム、下:ノイズ付与後の画像)

2) sigma=30の場合(上:ノイズの値のヒストグラム、下:ノイズ付与後の画像)

ノイズが山型の正規分布になっていることと、σを大きくすることでより大きいノイズが付与されていることがわかると思います。

まとめ

本日は画像へのガウシアンノイズの付与について紹介しました。

次回は、このノイズの評価方法や、ノイズ除去のアルゴリズム等を紹介してみたいと思います。

スポンサーリンク

シェアする

フォローする