OpenCV Reference

【OpenCV-Python】GaussianBlur(ガウシアンフィルタ)

OpenCVで画像のガウシアンフィルタ処理を行うには、GaussianBlur()関数を用います。

ガウシアンフィルタは、「ガウス関数のσの値を変えると、平滑化の効果を変えられる」という説明が多いかと思いますが、ガウシアンフィルタには、それよりも大事な、高周波成分を除去できるという効果があります。

高周波成分を除去するには、σの値は何でもいい訳ではないのですが、OpenCVでは、この高周波成分を除去できるσの値をカーネルのサイズから自動計算で計算させることもできます。

 

ガウシアンフィルタの構文

GaussianBlur( src, ksize, sigmaX[, dst[, sigmaY[, borderType]]] ) -> dst

引数

src ガウシアンフィルタ処理を行う画像データを指定します。
データタイプはuint8, uint16, int16, float32, float64に対応しています。
ksize ガウシアンフィルタのカーネルのサイズを(幅, 高さ)で指定します。
幅、高さの値は正の奇数の値である必要があります。
また、幅、高さに0を指定すると、σの値(sigmaX, sigmaY)から自動で計算します。
sigmaX X方向のσの値を指定します。
-1などのマイナスの値を指定するとカーネルのサイズから自動でσの値を計算します。
σ = 0.3 * (ksize – 1) * 0.5 – 1) * 0.8
sigmaY Y方向のσの値を指定します。
指定しないか、0を指定すると、sigmaXと同じσの値を用います。
sigmaXとsigmaYの両方が0の場合は、それぞれ、カーネルの幅と高さからσの値を自動で計算します。
borderType ボーダー処理の種類をBorderTypesのenumで指定します。


戻り値

dst ガウシアンフィルタ処理された画像データ

サンプルプログラム

ガウシアンフィルタ処理の一般的に行うシンプルなサンプルプログラムを以下に示します。

import cv2

src = cv2.imread("Text.bmp", cv2.IMREAD_UNCHANGED)

# ガウシアンフィルタ
dst = cv2.GaussianBlur(src, (3, 3), -1)

# ガウシアンフィルタ後の画像表示
cv2.imshow("Src Image", src)
cv2.imshow("GaussianBlur", dst)
cv2.waitKey()

実行結果

OpenCV Python GaussianBlur ガウシアンフィルタ

 

各種パラメータを設定したガウシアンフィルタ処理の例は以下の通りです。

import cv2

src = cv2.imread("Text.bmp", cv2.IMREAD_UNCHANGED)

# ガウシアンフィルタ
dst1 = cv2.GaussianBlur(
    src,    # 入力画像
    (7, 7), # カーネルのサイズ(幅、高さ)
    1.4,    # X方向のσの値(-1など負の値を指定するとカーネルサイズから自動計算)
    0,      # Y方向のσの値(0だとX方向と同じ)
    borderType = cv2.BORDER_DEFAULT  # ボーダー処理の種類
    )
# ガウシアンフィルタ(カーネルサイズを自動計算)
dst2 = cv2.GaussianBlur(
    src,    # 入力画像
    (0, 0), # カーネルのサイズを0にしてσの値からカーネルサイズを自動計算
    2       # X方向のσの値
    )

# 二値化処理後の画像表示
cv2.imshow("Src Image", src)
cv2.imshow("GaussianBlur1", dst1)
cv2.imshow("GaussianBlur2", dst2)
cv2.waitKey()

実行結果

OpenCV Python GaussianBlur ガウシアンフィルタ

OpenCV Python GaussianBlur ガウシアンフィルタ

 

ガウシアンフィルタのσの値について

高周波成分を除去するためには、σの値を大きくすれば良いという訳ではなく、最適な値があります。

OpenCVでは、sigmaX, sigmaYの値に負の値を指定するとカーネルのサイズ(幅、高さ)から下記の計算式から最適なσの値を計算してくれます。

σ = 0.3 * (ksize – 1) * 0.5 – 1) * 0.8

実際に、ガウシアンフィルタで用いられるカーネルの値は、getGaussianKernel()関数から取得することができます。

いくつか例を示すと

ksize= 3のとき
0.25, 0.5, 0.25

ksize= 5のとき
0.0625, 0.25, 0.375, 0.25, 0.0625

ksize= 7のとき
0.03125, 0.109375, 0.21875, 0.2825, 0.21875, 0.109375, 0.03125

となります。

 

ガウシアンフィルタのσの値と高周波成分の除去効果について

二次元の画像において、もっとも高周波な画像は、下図のような1画素おきの市松模様の画像となります。

OpenCV Python GaussianBlur ガウシアンフィルタ

この画像において、σの値を0.6, 0.8(自動計算), 3 と変えながらガウシアンフィルタ処理を行うとどのように変化するのか?を見てみたいと思います。

 

サンプルプログラム

import numpy as np
import cv2

def create_test_pattern():
    # テストパターンの作成
    data = np.array([
        [0, 255],
        [255, 0]
        ], dtype= np.uint8)
    img = np.tile(data, (16, 16))
    return img

# テストパターンの作成
src = create_test_pattern()

cv2.namedWindow("Src Image", cv2.WINDOW_NORMAL)
cv2.namedWindow("Gauss 0.3", cv2.WINDOW_NORMAL)
cv2.namedWindow("Gauss -1", cv2.WINDOW_NORMAL)
cv2.namedWindow("Gauss 3", cv2.WINDOW_NORMAL)

# σを変えながらガウシアン処理
gauss1 = cv2.GaussianBlur(src, (3, 3), 0.6) # σ=0.6
gauss2 = cv2.GaussianBlur(src, (3, 3), -1)  # σは自動計算(σ=0.8)
gauss3 = cv2.GaussianBlur(src, (3, 3), 3)   # σ=3

# ガウシアンフィルタ後の画像表示
cv2.imshow("Src Image", src)
cv2.imshow("Gauss 0.3", gauss1)
cv2.imshow("Gauss -1", gauss2)
cv2.imshow("Gauss 3", gauss3)
cv2.waitKey()

実行結果

OpenCV Python GaussianBlur ガウシアンフィルタ

左からσ=0.6,  σ=0.8(自動計算),  σ=3

 

このように、σの値は、単に大きい方が高周波成分を除去できるという訳ではなく、最適なσの値があり、このσの値は、OpenCVが自動で計算してくれる値を用いた方が高周波成分を除去できる事が確認できます。

 

参照ページ

OpenCV: Image Filtering
OpenCV: Image Filtering
ガウシアンフィルタの処理アルゴリズムとその効果
移動平均フィルタでは注目画素周辺の輝度値を単に平均していましが、一般的な画像では 注目画素に近い画素の輝度値は注目画素の輝度値と近い場合が多いですが、注目画素から遠くなればなるほど、注目画素の輝度値とは差が大きくなる場合が多くなります。 こ...
移動平均フィルタ VS ガウシアンフィルタ
いろいろと検索していたら、2008年の国家試験に以下のような問題があったらしい。 画像が最も平滑化される空間フィルタはどれか。 ただし、数字は重み係数を示す。 (参考) この問題、 1.ラプラシアンフィルタ 2.3x3の移動平均フィルタ 3...

コメント

タイトルとURLをコピーしました