OpenCV のぼかしフィルター

Salman Mehmood 2022年6月21日
OpenCV のぼかしフィルター

このデモでは、OpenCV で画像を滑らかにしたりぼかしたりする方法を紹介します。この記事の最後で、さまざまなタイプのブラーフィルターとその使用方法について説明します。

OpenCV でさまざまなタイプのブラーフィルターを使用する

ぼかしとも呼ばれるスムージングは​​、画像処理で最も一般的に使用される操作の 1つです。これは通常、画像からノイズを除去するために使用されます。

線形フィルターは簡単に実現でき、比較的高速であるため、さまざまな線形フィルターを使用できます。OpenCV で使用できるフィルターにはさまざまな種類があります。たとえば、同種、ガウス、中央値、または両側フィルターです。これらは個別に表示されます。

まず、均質フィルターを確認します。同種フィルターは単純であり、各出力ピクセルは同種フィルター内の隣接するカーネルの平均です。

すべてのピクセルは同じ重みで寄与します。そのため、これらは同種フィルターと呼ばれます。言い換えれば、カーネルは、画像に適用または畳み込むことができる形状です。

numpy は、この種の 2 乗カーネルを作成します。したがって、同種フィルターでは、カーネルはこのイメージのようになります。

Opencv ブラーの例 1

同種フィルターでは、カーネル K は、1 をカーネルの幅で割った値にカーネルの高さを掛けたものに等しくなります。この式を使用して 5x5 のカーネルを使用する場合、K は 1 を 25 で割った値になり、5x5 のカーネルマトリックスは 1 になります。

Opencv ブラーの例 2

次に、filter2D() または同種フィルターを使用した画像フィルタリング用にこのカーネルを作成する必要があります。まず、imread() メソッドを使用して画像を読み取ります。

IMG = cv2.imread("opencv-logo.jpg")

matplotlib は画像を RGB 形式で読み取り、OpenCV は画像を BGR 形式で読み取るため、画像を BGR から RGB に変換する必要があります。

IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

float32 データタイプで ones() メソッドを使用して 5x5 カーネルを定義する必要があり、それを 25 で除算します。

K = np.ones((5, 5), np.float32) / 25

これで、定義されたカーネルを支援することにより、宛先イメージを定義できます。均一フィルターには、filter2D() と呼ばれるメソッドが使用されます。

最初のパラメーターはソースイメージ、2 番目は宛先イメージの目的の深度、3 番目はカーネルです。

HMG = cv2.filter2D(IMG, -1, K)

次の行では、for ループを繰り返しており、このループを介して matplotlib に 1x2 形式で画像を表示します。

for j in range(2):
    plot.subplot(1, 2, j + 1), plot.imshow(IMGS[j], "gray")

完全なサンプルソースコード:

import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("opencv-logo.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)


T = ["Original IMG", "2D Convolution"]
IMGS = [IMG, HMG]

for j in range(2):
    plot.subplot(1, 2, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

コーナーに小さなノイズが見られます。この画像に 2D コンボリューションを適用した後、コーナーはわずかに滑らかまたはぼやけています。このぼかしによってノイズが除去または抑制されるため、これは filter2D() メソッドを使用して画像をぼかします。

Opencv ブラー出力 1

ぼかしフィルター

一次元画像は、ローパスフィルターまたはハイパスフィルターでフィルタリングできます。ローパスフィルターは画像のノイズやぼやけなどを取り除くのに役立ち、ハイパスフィルターは画像のエッジを見つけるのに役立ちます。

ぼやけた画像を実現するには、ローパスフィルターを使用して画像を変換する必要があります。OpenCV ではさまざまな種類のアルゴリズムを利用できます。最初のアルゴリズムは blur() メソッドです。

blur() メソッドは平均化メソッドとも呼ばれ、平均化アルゴリズムを適用してぼやけた画像を作成するために使用します。このメソッドは 2つのパラメーターを取ります。1つ目はイメージで、2つ目はカーネルです。これは(5,5)になります。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("opencv-logo.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))

T = ["Original IMG", "2D Convolution", "Blur"]
IMGS = [IMG, HMG, BL]

for j in range(3):
    plot.subplot(1, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

同じ種類のカーネルを両方の関数に適用したため、結果は 2D コンボリューションとブラーの間でほぼ同じに見えます。

Opencv ブラー出力 2

ガウスフィルター

次のアルゴリズムであるガウスフィルターアルゴリズムを見てみましょう。ガウスフィルターは、x 方向と y 方向の両方で異なるウェイトカーネルを使用することに他なりません。

出力では、ピクセルはカーネルの中央に配置されており、重みが大きくなっています。重みは、近隣の中心からの距離とともに減少します。

小さい方のピクセルは側面にあり、大きい方のピクセルは中央にあります。

5x5 カーネルを使用すると、その結果は画像に示されているようになります。

Opencv ブラーの例 3

OpenCV で GaussianBlur() メソッドを使用する方法を見てみましょう。パラメータは blur() メソッドと同じであるため、最初のパラメータは入力イメージ、2 番目のパラメータはカーネル、3 番目のパラメータは SigmaX 値です。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("eye.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)

T = ["Original IMG", "2D Convolution", "Blur", "GaussianBlur"]
IMGS = [IMG, HMG, BL, GB]

for j in range(4):
    plot.subplot(2, 2, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

GaussianBlur() メソッドの結果は、他のぼかしメソッドよりも優れていることがわかります。

ノイズが多すぎる元の画像を見てください。GaussianBlur() メソッドを適用すると、すべてのノイズが除去されます。

したがって、GaussianBlur() メソッドは、画像から高周波ノイズを除去するために特別に設計されています。

Opencv ブラー出力 3

メディアンフィルター

メディアンフィルターは、各ピクセル値を隣接するピクセルのメディアンに置き換えるものです。medianBlur() メソッドは、塩コショウノイズのある画像を処理する場合に最適です。

塩コショウのノイズについてもっと知りたい場合は、このリンクをたどってください。

ここに画像があります。一部のピクセルは歪んでおり、一部は白い点または白いノイズであり、いくつかは黒いノイズが見られる場所です。ピクセルが塩のように歪んでいて、黒いピクセルがコショウのように見えるため、塩とコショウのノイズと呼ばれます。

水のサンプル画像

この画像を medianBlur() メソッドのソースとして使用してみましょう。ソースイメージが最初のパラメーターになり、2 番目がカーネルサイズになります。

カーネルサイズは、1 を除いて、3、5、7 などのように奇数である必要があることに注意する必要があります。1 を使用すると、元のイメージが表示されます。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("water.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)
MB = cv2.medianBlur(IMG, 5)

T = ["Original IMG", "2D Convolution", "Blur", "GaussianBlur", "medianBlur"]
IMGS = [IMG, HMG, BL, GB, MB]

for j in range(5):
    plot.subplot(2, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

medianBlur() メソッドを使用して得られる最良の結果を以下に示します。

Opencv ブラー出力 4

バイラテラルフィルター

バイラテラルフィルターと呼ばれる最後のフィルターを見てみましょう。そのため、他のフィルターを使用することで、ノイズを解消するだけでなく、エッジを滑らかにしました。

エッジを保持する必要がある場合があります。つまり、画像がぼやけていても、すべてのエッジがシャープなままです。

bilateralFilter() メソッドは、最初のパラメーターとして画像を取ります。2 番目のパラメーターはフィルター中に使用される各ピクセルの直径、3 番目のパラメーターはシグマカラー、4 番目のパラメーターはシグマスペースです。

シグマカラーはカラースペースのフィルターシグマであり、シグマスペースは座標スペースのフィルターシグマです。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("lena-1.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)
MB = cv2.medianBlur(IMG, 5)
BF = cv2.bilateralFilter(IMG, 9, 75, 75)

T = [
    "Original IMG",
    "2D Convolution",
    "Blur",
    "GaussianBlur",
    "medianBlur",
    "bilateralFilter",
]
IMGS = [IMG, HMG, BL, GB, MB, BF]
plot.figure(figsize=(8, 6))
for j in range(6):
    plot.subplot(2, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

bilateralFilter() メソッドが適用された場合に、エッジがどのように保存されるかを確認してください。バイラテラルフィルターは、エッジをシャープに保ちながらノイズを除去するのに非常に効果的です。

Opencv ブラー出力 5

著者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

関連記事 - Python OpenCV