PythonとOpenCVのfilter2Dメソッドを使って画像にぼかし、エッジ検出などをやる方法

スポンサーリンク

この記事では,OpenCV の filter2D() メソッドを用いて,画像の鮮鋭化やぼかし,エッジ検出などのフィルタリングを行う方法を学びます.では、さっそく始めましょう。

こちらもご覧ください。

スポンサーリンク

OpenCV のフィルタリング2D()関数の紹介

画像処理で画像を扱うとき,周囲のピクセル強度値に基づいて画像のピクセル強度値を変更するために,関数 filter2D() が利用されます.このメソッドは、イメージの特定の特徴を強調したり削除したりして、新しいイメージを作成することができます

python で filter2D() 関数を定義するためのシンタックスは以下の通りです。

resulting_image = cv2.filter2D(src, ddepth, kernel)
  • src: フィットラーを適用する元画像。画像をピクセルの輝度値で表現した行列です。
  • ddepth: 出力画像の望ましい深さです。値 -1 は、結果画像がソース画像と同じ深さになることを表します。
  • kernel: カーネルは,画像に適用されるフィルタ行列です.

より正式には,関数 filter2D() は,画像をカーネルで畳み込み,その結果,画像をぼかしたり,シャープにしたり,画像の特徴を強調したりします.

カーネルとは何ですか?

カーネルは、コンボリューション行列やマスクとも呼ばれ、現在のピクセルの強度値を計算するために、周囲のピクセル値のどれだけの部分を取るべきかを表す値を含む小さな2次元行列です。

通常、カーネルは3×3、5×5、7×7といった奇数の長さの正方行列です。

このようにカーネルは重み付け行列として機能し、画像処理において画像のぼかし、画像の鮮鋭化、画像のエッジ検出などに利用される。

これは、画像とカーネルの畳み込みによって行われる。

コンボリューションとは?

画像処理においてコンボリューションとは、カーネルと元画像の一部を要素ごとに掛け合わせ、画素を表す新しい1つのデータ点を生成することで、画像のあらゆる可能な部分に対してそれを行い、新しい画像を作成することです。

コンボリューションでは、カーネルと同じサイズの部分行列を元画像から取り出し、元画像の各要素とカーネルの対応する要素を掛け合わせ、前の計算を加算してデータを正規化し、データを画素値として表します。

下図のような例を考えてみましょう。

import cv2
import numpy as np
# Loading source image
src_image = cv2.imread("pug-dog.jpg")
# Defining the kernel of size 3x3
kernel = np.array([
  [0, -1, 0],
  [-1, 5, -1],
  [0, -1, 0]
])
 
resulting_image = cv2.filter2D(src_image, -1, kernel)
 
cv2.imshow("original image", src_image)
cv2.imshow("filter2d image", resulting_image)
cv2.imwrite("Filter2d Sharpened Image.jpg", resulting_image)
cv2.waitKey()
cv2.destroyAllWindows()

画像の畳み込みは、元画像より小さいサイズの画像を得ることができます。

この差はカーネルの大きさに依存します。

しかし、ここで説明するような対処法があります。

OpenCV の filter2d() を異なるカーネルで利用する場合

異なるカーネルを持つ画像に対して filter2d() 関数を適用し,どのような結果が得られるかを見てみましょう.この例では、以下のような画像を用います。

import cv2
import numpy as np
# Loading source image
src_image = cv2.imread("pug-dog.jpg")
# Defining the kernel of size 3x3
kernel = np.array([
  [1, 1, 1],
  [1, 1, 1],
  [1, 1, 1]
]) / 9
 
resulting_image = cv2.filter2D(src_image, -1, kernel)
 
cv2.imshow("original image", src_image)
cv2.imshow("filter2d image", resulting_image)
cv2.imwrite("Filter2d Blur Image.jpg", resulting_image)
cv2.waitKey()
cv2.destroyAllWindows()

1. 画像をシャープにする

画像のシャープ化について、より詳しく知ることができます。

この例では、上の画像をシャープにします。

import cv2
import numpy as np
# Loading source image
src_image = cv2.imread("pug-dog.jpg")
# Defining the kernel of size 3x3
kernel = np.array([
  [-1, -1, -1],
  [-1, 8, -1],
  [-1, -1, -1]
])
 
resulting_image = cv2.filter2D(src_image, -1, kernel)
 
cv2.imshow("original image", src_image)
cv2.imshow("filter2d image", resulting_image)
cv2.imwrite("Filter2d Outline Image.jpg", resulting_image)
cv2.waitKey()
cv2.destroyAllWindows()
import cv2
import numpy as np
# Loading source image
src_image = cv2.imread("pug-dog.jpg")
# Defining the Emboss kernel of size 3x3
kernel = np.array([
  [-2, -1, 0],
  [-1, 1, 1],
  [0, 1, 2]
])
 
resulting_image = cv2.filter2D(src_image, -1, kernel)
 
cv2.imshow("original image", src_image)
cv2.imshow("filter2d image", resulting_image)
cv2.imwrite("Filter2d Emboss Image.jpg", resulting_image)
cv2.waitKey()
cv2.destroyAllWindows()

2. 画像にぼかしを入れる

import cv2
import numpy as np
# Loading source image
src_image = cv2.imread("pug-dog.jpg")
# Defining the Sobel kernel of size 3x3
kernel = np.array([
  [-1, 0, 1],
  [-2, 0, 2],
  [-1, 0, 1]
])
 
resulting_image = cv2.filter2D(src_image, -1, kernel)
 
cv2.imshow("original image", src_image)
cv2.imshow("filter2d image", resulting_image)
cv2.imwrite("Filter2d Sobel Image.jpg", resulting_image)
cv2.waitKey()
cv2.destroyAllWindows()
Convolution Image Processing Example 1

3. 画像上のアウトラインエッジ検出

OpenCV の filter2D() 関数によるエッジ検出を見てみましょう.

Filter2d Source Image
Filter2d Sharpened Image

Using Emboss Filter

Fake Tags
Fake Tags

Using Sobel Filter

False Tags
Fake Tags

まとめ

この記事では、画像処理における畳み込みとカーネルについて、そして画像を操作するために OpenCV の filter2D() 関数が python でどのように使われるかを学びました。

これで、様々なカーネルフィルタを試して、異なる画像効果を得ることができます。

お読みいただきありがとうございました。

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