OpenCV
前回、PythonのOpenCVで画像データをR(赤)、G(緑)、B(青)のデータに分離する方法を紹介しました。
今回もOpenCVネタで4種のノイズ除去フィルタ(blue、GaussianBlur、medianBlur、birateralFilter)の使い方を紹介します。
ちなみに細かなノイズを除去するためにはぼかす、つまりは画像の平滑化をすることと同意のようです。
使う画像は前回と同じ画像ですが、ファイル名を「python-opencv13-1.jpg」としています。
画像を読み込むまでのプログラムはこんな感じです。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
それでは始めていきましょう。
Blur:ぼかし
まずは「Blur(ぼかし)」フィルタです。
使い方は「cv2.blur(読み込んだ画像データ, (xの範囲, yの範囲))」です。
xの範囲、yの範囲とはある点を中心に横にxピクセル分、縦にyピクセル分の範囲のことで、この中に含まれるピクセルをその平均値に変更します。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize_x = 10
ksize_y = 10
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
blurred = cv2.blur(img, (ksize_x, ksize_y))
output = os.path.join(default_dirpath, "python-opencv13-2.png")
cv2.imwrite(output, blurred)
元の画像
Blurフィルタ後の画像
ちなみにフィルタの範囲を変えるだけでも結構見栄えが変わります。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize_x = 10
ksize_y = 1
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
blurred = cv2.blur(img, (ksize_x, ksize_y))
output = os.path.join(default_dirpath, "python-opencv13-3.png")
cv2.imwrite(output, blurred)
x:10ピクセル、y:10ピクセル
x:10ピクセル、y:1ピクセル
GaussianBlur:ガウシアンぼかし
次はGaussianBlur(ガウシアンぼかし)で、ガウス分布を使ったぼかしの方法です。
使い方は「cv2.GaussianBlur(読み込んだ画像, (xの範囲, yの範囲), xのシグマ, yのシグマ)」です。
ちなみにガウス分布はこんな式で表されます。
\(f(x) = a \times exp \{ – \frac{(x – \mu)^2}{2\sigma^2}\}\)
aはピークの高さ、\(\mu\)はピーク位置なので変更しません。
そして\(\sigma\)はピークの広がり具合で、ここがぼかし具合となります。
それが「xのシグマ」、「yのシグマ」です。
ガウス分布の関数はこちらの記事で紹介していますのでよかったらどうぞ。
まずはxのシグマもyのシグマも0にして試してみます。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize_x = 11
ksize_y = 11
sigma_x = 0
sigma_y = 0
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
GaussianBlurred = cv2.GaussianBlur(img, (ksize_x, ksize_y), sigma_x, sigma_y)
output = os.path.join(default_dirpath, "python-opencv13-4.png")
cv2.imwrite(output, GaussianBlurred)
元の画像
範囲:11ピクセル、シグマ:0の画像
次にさらにシグマを5にして試してみます。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize_x = 11
ksize_y = 11
sigma_x = 5
sigma_y = 5
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
GaussianBlurred = cv2.GaussianBlur(img, (ksize_x, ksize_y), sigma_x, sigma_y)
output = os.path.join(default_dirpath, "python-opencv13-5.png")
cv2.imwrite(output, GaussianBlurred)
元の画像
範囲:11ピクセル、シグマ:5の画像
シグマ0とシグマ5を比較してみるとこんな感じ。
範囲:11ピクセル、シグマ:0の画像
範囲:11ピクセル、シグマ:5の画像
ちなみにGaussianBlurフィルタの範囲は奇数である必要があり、偶数にするとエラーとなります。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize_x = 10
ksize_y = 10
sigma_x = 5
sigma_y = 5
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
GaussianBlurred = cv2.GaussianBlur(img, (ksize_x, ksize_y), sigma_x, sigma_y)
output = os.path.join(default_dirpath, "python-opencv13-6.png")
cv2.imwrite(output, GaussianBlurred)
実行結果
---------------------------------------------------------------------------
error Traceback (most recent call last)
Cell In[20], line 17
13 filepath = os.path.join(default_dirpath, filename)
15 img = cv2.imread(filepath, cv2.IMREAD_COLOR)
---> 17 GaussianBlurred = cv2.GaussianBlur(img, (ksize_x, ksize_y), sigma_x, sigma_y)
19 output = os.path.join(default_dirpath, "python-opencv13-6.png")
20 cv2.imwrite(output, GaussianBlurred)
error: OpenCV(4.9.0) /Users/runner/work/opencv-python/opencv-python/opencv/modules/imgproc
/src/smooth.dispatch.cpp:294: error: (-215:Assertion failed) ksize.width > 0 && ksize.width
% 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1 in function 'createGaussianKernels'
medianBlur:メディアンぼかし
次はmedialBlur(メディアンぼかし)で、範囲内のピクセルの中央値(小さい順に並べたときに真ん中にくる値)に全てのピクセルの値を設定するというものです。
使い方は「cv2.medianBlur(読み込んだ画像, xyの範囲)」です。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize = 11
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
medianBlurred = cv2.medianBlur(img, ksize)
output = os.path.join(default_dirpath, "python-opencv13-7.png")
cv2.imwrite(output, medianBlurred)
元の画像
メディアンぼかし後の画像
またメディアンぼかしも範囲は奇数である必要があり、偶数にするとエラーとなります。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
ksize = 10
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
medianBlurred = cv2.medianBlur(img, ksize)
output = os.path.join(default_dirpath, "python-opencv13-8.png")
cv2.imwrite(output, medianBlurred)
実行結果
---------------------------------------------------------------------------
error Traceback (most recent call last)
Cell In[17], line 14
10 filepath = os.path.join(default_dirpath, filename)
12 img = cv2.imread(filepath, cv2.IMREAD_COLOR)
---> 14 medianBlurred = cv2.medianBlur(img, ksize)
16 output = os.path.join(default_dirpath, "python-opencv13-8.png")
17 cv2.imwrite(output, medianBlurred)
error: OpenCV(4.9.0) /Users/runner/work/opencv-python/opencv-python/opencv/modules/
imgproc/src/median_blur.dispatch.cpp:285: error: (-215:Assertion failed) (ksize % 2 == 1)
&& (_src0.dims() <= 2 ) in function 'medianBlur'
bilateralFilter:バイラテラルフィルタ
bilateralFilter(バイラテラルフィルタ)はピクセル間の空間的な距離も考慮したフィルタ方法(らしい)です。
使い方は「cv2.bilateralFilter(読み込んだ画像, フィルタサイズ, sigmaColor, sigmaSpace)」です。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
d = 101
sigmaColor = 100
sigmaSpace = 100
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
bilateralFiltered = cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)
output = os.path.join(default_dirpath, "python-opencv13-9.png")
cv2.imwrite(output, bilateralFiltered)
元の画像
バイラテラルフィルタ後の画像
バイラテラルフィルタもフィルタサイズは奇数である必要があり、偶数の場合はエラーとなります。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv13-1.jpg"
d = 100
sigmaColor = 100
sigmaSpace = 100
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
bilateralFiltered = cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)
output = os.path.join(default_dirpath, "python-opencv13-10.png")
cv2.imwrite(output, bilateralFiltered)
実行結果
---------------------------------------------------------------------------
error Traceback (most recent call last)
Cell In[2], line 16
12 filepath = os.path.join(default_dirpath, filename)
14 img = cv2.imread(filepath, cv2.IMREAD_COLOR)
---> 16 bilateralFiltered = cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)
18 output = os.path.join(default_dirpath, "python-opencv13-10.png")
19 cv2.imwrite(output, bilateralFiltered)
error: OpenCV(4.9.0) /Users/runner/work/opencv-python/opencv-python/opencv/modules/
imgproc/src/bilateral_filter.dispatch.cpp:409: error: (-215:Assertion failed) !_src.empty()
in function 'bilateralFilter'
次回はOpenCVのfilter2Dを使って画像をアンシャープマスキング(鮮鋭化)する方法を紹介します。
ではでは今回はこんな感じで。
コメント