【Python・OpenCV】4種類のノイズ除去フィルターの使い方と特徴について

※当サイトではアフィリエイト広告を利用しています

Python プログラミング 画像処理

【Python・OpenCV】4種類のノイズ除去フィルターの使い方と特徴について

2023-06-07

はじめに

OpenCVは、画像処理やコンピュータビジョンにおいて非常に人気のあるライブラリです。その中でも、ノイズ除去フィルターは画像のノイズ除去やエッジの滑らか化などのタスクに広く使用されます。この記事では、OpenCVを使ったノイズ除去グフィルターの種類と使い方について、Pythonのサンプルコードを交えて解説します。

本記事では、画像処理の基本的なノイズ除去フィルターを紹介していますが、Non-Local Meansアルゴリズムによる効果的なノイズ除去フィルターについて、下記の記事で紹介しています。
用途の応じて使い分けてください。

ノイズ除去フィルターとは

ノイズ除去フィルターは、画像処理において画像のノイズを除去したり、エッジを滑らかにするために使用されるフィルタリング手法です。画像の各ピクセルに対して、周囲のピクセル値の統計情報を利用して中心のピクセル値を修正します。

ノイズ除去フィルターの種類と特徴

平均化フィルター(Blur)

平均化フィルターは、画像のノイズ除去によく用いられます。各ピクセルの値をその周囲のピクセルの平均値で置き換えます。平均化フィルターは、周囲のピクセルの情報を均等に重みづけするため、ノイズを抑える効果がありますが、画像のエッジ情報も同様にぼかしてしまう特徴があります。

計算方法:
画像の各ピクセルにおいて、周囲の近傍ピクセルの値を取得し、それらの平均値を計算します。そして、計算された平均値を元のピクセルの値と置き換えます。この操作は、画像内の各ピクセルに対して行われ、画像全体に平滑化効果を与えます。

cv2.blur関数

画像の各ピクセルにおける周囲の近傍ピクセルの縦横サイズ(カーネル サイズ)をタプルで指定します。

cv2.blur(入力画像, ksize[, anchor[, borderType]])

引数

名称説明
入力画像(必須)入力画像
ksize(必須)カーネルの縦横(X,Y)のサイズのタプル
anchor(オプション)カーネル内のフィルタ対象の座標。デフォルト値は(-1,-1) はアンカーがカーネルの中心にあることを意味します。
borderType(オプション)画像の外側のピクセルを外挿するために使用される境界モード。。BorderTypesを参照してください。

戻り値

フィルター後の画像データ

サンプルコード

import cv2

# 画像の読み込み
image = cv2.imread('image.jpg')

# カーネルサイズの設定
kernel_size = 5

# 平均化フィルターの適用
blurred = cv2.blur(image, (kernel_size, kernel_size))

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(kernel_size=" + str(kernel_size) + ")", blurred)


# カーネルサイズの設定
kernel_size = 11

# 平均化フィルターの適用
blurred = cv2.blur(image, (kernel_size, kernel_size))

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(kernel_size=" + str(kernel_size) + ")", blurred)

cv2.waitKey(0)
cv2.destroyAllWindows()

ガウシアンフィルター(Gaussian Filter)

ガウシアンフィルターは、ピクセルの周囲のピクセル値をガウス分布に基づいて重みづけして平滑化するフィルターです。周辺のピクセルによって中心のピクセルがより重視されるため、平均化フィルターよりもエッジを滑らかにする効果があります。ノイズ除去や画像のぼかし効果を求める場合に適しています。

計算方法:
ガウシアンぼかしでは、各ピクセルの値を、周囲の近傍ピクセルの値と重みの積の総和で置き換えます。重みはガウス関数によって計算され、ピクセル間の距離に基づいて減衰します。重み付き平均を計算することにより、ピクセルの値をぼかし効果を持つ周囲の値に近づけます。

cv2.GaussianBlur関数

cv2.GaussianBlur関数はcv2.blur関数と同様に画像の各ピクセルにおける周囲の近傍ピクセルの縦横サイズ(カーネル サイズ)をタプルで指定します。

cv2.GaussianBlur(入力画像, ksize, sigmaX[, sigmaY[, borderType]])

引数

名称説明
入力画像(必須)入力画像
ksize(必須)カーネルの縦横(X,Y)のサイズのタプル
sigmaX(オプション)カーネル内のフィルタ対象の座標。
sigmaY(オプション)Y方向のカーネル標準偏差。sigmaYが0の場合はsigmaXと等しくなるように設定され、両方のsigmaが0の場合はそれぞれ ksize.width と ksize.height から計算されます(詳細についてはgetGaussianKernelを参照してください)。このすべてのセマンティクスが将来変更される可能性があるかどうかに関係なく、結果を完全に制御するには、ksize、sigmaX、および sigmaY をすべて指定することをお勧めします。
borderType(オプション)画像の外側のピクセルを外挿するために使用される境界モード。BorderTypesを参照してください。BORDER_WRAPはサポートされていません。

戻り値

フィルター後の画像データ(ndarray)

サンプルコード

import cv2

# 画像の読み込み
image = cv2.imread('image.jpg')

# カーネルサイズの設定
kernel_size = 5

# sigmaの設定
sigma = 0

# ガウシアンフィルターの適用
blurred = cv2.GaussianBlur(image, (kernel_size, kernel_size), sigma)

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(kernel_size=" + str(kernel_size) + ", sigma=" + str(sigma) + ")", blurred)


# カーネルサイズの設定
kernel_size = 11

# sigmaの設定
sigma = 0

# ガウシアンフィルターの適用
blurred = cv2.GaussianBlur(image, (kernel_size, kernel_size), sigma)

cv2.imshow("Smoothed Image(kernel_size=" + str(kernel_size) + ", sigma=" + str(sigma) + ")", blurred)

cv2.waitKey(0)
cv2.destroyAllWindows()

メディアンフィルター(Median Filter)

メディアンフィルターは、各ピクセルの値をその周囲のピクセル値の中央値で置き換えるフィルターです。このフィルターは、ノイズの影響を受けにくく、エッジを保持しつつノイズを除去することができます。特に、ソルト・ペッパーノイズなどのスパイクノイズ(画像中に散在する明るい点や暗い点)効果的です。

計算方法:

  1. メディアンフィルターの適用対象となるピクセルを選択します。
  2. 選択したピクセルを中心として、周囲のピクセルを取得します。周囲のピクセルは、通常は注目ピクセルの周囲の正方形領域内に存在します。
  3. 周囲のピクセルの値を取得し、昇順に並び替えます。
  4. ピクセル値の中央値を求めます。奇数個のピクセルがある場合は、中央に位置する値が中央値となります。偶数個のピクセルがある場合は、中央に位置する2つの値の平均が中央値となります。
  5. 中央値を注目ピクセルの新しい値として採用します。

cv2.medianBlur関数

cv2.medianBlur関数もcv2.blur関数と同様に画像の各ピクセルにおける周囲の近傍ピクセルの縦横サイズ(カーネル サイズ)を指定しますが、縦横を個別ではなく同じ値の整数で指定します。

cv2.medianBlur(入力画像, ksize)

引数

名称説明
入力画像(必須)入力画像
ksize(必須)カーネルの縦横(X,Y)のサイズのタプル

戻り値

フィルター後の画像データ

サンプルコード

import cv2

# 画像の読み込み
image = cv2.imread('【Python・OpenCV】スムージング フィルターの使い方/images/image.jpg')

# カーネルサイズの設定
kernel_size = 5

# メディアンフィルターの適用
blurred = cv2.medianBlur(image, kernel_size)

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(kernel_size=" + str(kernel_size) + ")", blurred)


# カーネルサイズの設定
kernel_size = 11

# メディアンフィルターの適用
blurred = cv2.medianBlur(image, kernel_size)

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(kernel_size=" + str(kernel_size) + ")", blurred)

cv2.waitKey(0)
cv2.destroyAllWindows()

双方向フィルタ(Bilateral Filter)

双方向フィルタは、画像のぼかし効果を得ながらも、エッジ情報を保持するための手法です。この手法では、ピクセルの値を周囲の近傍ピクセルとの相似性に基づいて置き換えます。双方向フィルタは、空間的な距離と輝度の差異によって重みを計算し、ぼかしの度合いを制御します。

計算方法:
双方向フィルタでは、以下の2つの要素を考慮します。

  1. 空間的な距離の重み: ピクセル間の空間的な距離が近いほど、重みが大きくなります。これにより、近傍のピクセルとの相似性に基づいた平滑化が行われます。
  2. 輝度の差異の重み: ピクセル間の輝度の差異が小さいほど、重みが大きくなります。これにより、エッジ情報を保持しながらぼかし効果が得られます。

具体的な計算手順は以下の通りです。

  1. 処理対象のピクセルを中心とする領域を定義します。
  2. 領域内の各ピクセルについて、空間的な距離と輝度の差異を計算します。
  3. 距離と差異に基づいて、各ピクセルの重みを計算します。
  4. 重み付き平均を使用して、処理対象のピクセルの値を置き換えます。
  5. 2から4の手順を画像内の全てのピクセルに対して適用します。

双方向フィルタは、周囲のピクセルとの相似性に基づいてぼかしを行うため、エッジの保持や画像の詳細な情報の損失を最小限に抑えることができます。しかし、計算量が他の手法と比べて多くなるため、実行時間が長くなる可能性があります。

cv2.bilateralFilter関数

cv2.bilateralFilter関数の引数には、以下があります。

cv2.bilateralFilter(入力画像, d, sigmaColor, sigmaSpace[, borderType])

引数

名称説明
入力画像(必須)入力画像
d(必須)フィルタサイズ。ピクセルの近傍領域の直径を指定します。奇数の値を指定します。
sigmaColor(必須色空間におけるフィルタの標準偏差。この値が大きいほど、より広い範囲の色情報を考慮します。
sigmaSpace必須座標空間におけるフィルタの標準偏差。この値が大きいほど、より広い範囲のピクセルを考慮します。
borderType(オプション)画像の外側のピクセルを外挿するために使用される境界モード。BorderTypesを参照してください。

戻り値

フィルター後の画像データ

サンプルコード

import cv2

# 入力画像の読み込み
image = cv2.imread('【Python・OpenCV】スムージング フィルターの使い方/images/image.jpg')

# フィルタサイズの設定
d = 5

# 色空間におけるフィルタの標準偏差の設定
sigmaColor = 75

# 座標空間におけるフィルタの標準偏差の設定
sigmaSpace = 75

# バイラテラルフィルタの適用
blurred = cv2.bilateralFilter(image, d, sigmaColor, sigmaSpace)

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(d=" + str(d) + ", sigmaColor=" + str(sigmaColor) + ", sigmaSpace=" + str(sigmaSpace) + ")", blurred)


# フィルタサイズの設定
d = 15

# 色空間におけるフィルタの標準偏差の設定
sigmaColor = 75

# 座標空間におけるフィルタの標準偏差の設定
sigmaSpace = 75

# バイラテラルフィルタの適用
blurred = cv2.bilateralFilter(image, d, sigmaColor, sigmaSpace)

# 結果の表示
cv2.imshow("Original Image", image)
cv2.imshow("Smoothed Image(d=" + str(d) + ", sigmaColor=" + str(sigmaColor) + ", sigmaSpace=" + str(sigmaSpace) + ")", blurred)


cv2.waitKey(0)
cv2.destroyAllWindows()

おわりに

この記事では、OpenCVを使用したノイズ除去フィルターの種類と使い方について解説しました。ノイズ除去フィルターは、画像のノイズ除去やエッジの滑らか化などに広く使用されます。それぞれのフィルターの特徴を活かし、上手に使い分けてOpenCVを使ったノイズ除去フィルターの活用に挑戦してみてください。

最後までご覧いただきありがとうございました。

■(広告)OpenCVの参考書としてどうぞ!■

参考リンク

-Python, プログラミング, 画像処理
-