Edited at

OpenCVで各種フィルター処理をする(グラディエント、ハイパス、ラプラシアン、ガウシアン)

More than 3 years have passed since last update.


はじめに

OpenCV(Open Source Computer Vision Library)はBSDライセンスの映像/画像処理ライブラリ集です。画像のフィルタ処理、テンプレートマッチング、物体認識、映像解析、機械学習などのアルゴリズムが多数用意されています。

OpenCVを使った動体追跡の例 (OpenCV Google Summer of Code 2015)

https://www.youtube.com/watch?v=OUbUFn71S4s

インストールと簡単な使い方はこちら

http://qiita.com/olympic2020/items/d5d475a446ec9c73261e

静止画像のフィルター処理についてはこちら

OpenCVでエッジ検出してみる

動画ファイルの処理についてはこちら

OpenCVで動画をリアルタイムに変換してみる

OpenCVでWebカメラ/ビデオカメラの動画をリアルタイムに変換してみる

今回は、各種フィルターを適用してみます。


各種フィルター

今回紹介するフィルターは以下になります。


  • ハイパス フィルタ

     方向に関係なくエッジを抽出することができます。

     


  • グラディエント フィルタ

     1次微分フィルタと呼ばれることもあります。1方向のエッジ抽出を行うことができます。カーネルを回転させることで、上下方向、左右方向のどの方向のエッジを抽出するのかを指定することができます。

     


  • ラプラシアン フィルタ

     2次微分フィルタと呼ばれることもあります。平面の全方向のエッジ抽出します。

     


  • ガウシアン フィルタ

     平滑化フィルタの1種です。ノイズ除去に用います。ただし、カーネルが粗いと、かえってノイズがのってしまうこともあります。

     



プログラム

各種フィルター処理を行うための行列をカーネルとよびます。

プログラムは、各フィルタに対して、以下の処理を行っています。


  1. カーネルを定義

  2. cv2.filter2D()を適用する

  3. ファイルに保存する


filter.py

import cv2

import numpy as np

# 定数定義
FILE_ORG = "img.png"
FILE_GRAY = "gray.png"
FILE_GRADIENT = "gradient.png"
FILE_HIGH_PASS = "highpass.png"
FILE_LAPLACIAN_3x3 = "laplacian3x3.png"
FILE_LAPLACIAN_5x5 = "laplacian5x5.png"
FILE_GAUSSIAN = "gaussian.png"

# 元の画像を読み込む
img_org = cv2.imread(FILE_ORG, cv2.IMREAD_COLOR)

# グレースケール変換
img_gray = cv2.cvtColor(img_org, cv2.COLOR_BGR2GRAY)
cv2.imwrite(FILE_GRAY, img_gray)

# グラディエント フィルタ(3x3)
kernel_gradient_3x3 = np.array([
[ 1, 1, 1],
[ 0, 0, 0],
[-1, -1, -1]
], np.float32)
img_gradient_3x3 = cv2.filter2D(img_gray, -1, kernel_gradient_3x3)
cv2.imwrite(FILE_GRADIENT_3x3, img_gradient_3x3)

# グラディエント フィルタ(5x5)
kernel_gradient_5x5 = np.array([
[ 5, 5, 5, 5, 5],
[ 3, 3, 3, 3, 3],
[ 0, 0, 0, 0, 0],
[-3, -3, -3, -3, -3],
[-5, -5, -5, -5, -5]
], np.float32)
img_gradient_5x5 = cv2.filter2D(img_gray, -1, kernel_gradient_5x5)
cv2.imwrite(FILE_GRADIENT_5x5, img_gradient_5x5)

# ハイパス フィルタ
kernel_high_pass = np.array([
[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]
], np.float32)
img_high_pass = cv2.filter2D(img_gray, -1, kernel_high_pass)
cv2.imwrite(FILE_HIGH_PASS, img_high_pass)

# ラプラシアン フィルタ(3×3)
kernel_laplacian_3x3 = np.array([
[1, 1, 1],
[1, -8, 1],
[1, 1, 1]
], np.float32)
img_laplacian_3x3 = cv2.filter2D(img_gray, -1, kernel_laplacian_3x3)
cv2.imwrite(FILE_LAPLACIAN_3x3, img_laplacian_3x3)

# ラプラシアン フィルタ(5x5)
kernel_laplacian_5x5 = np.array([
[-1, -3, -4, -3, -1],
[-3, 0, 6, 0, -3],
[-4, 6, 20, 6, -4],
[-3, 0, 6, 0, -3],
[-1, -3, -4, -3, -1]
], np.float32)
img_laplacian_5x5 = cv2.filter2D(img_gray, -1, kernel_laplacian_5x5)
cv2.imwrite(FILE_LAPLACIAN_5x5, img_laplacian_5x5)

# ガウシアン フィルタ
kernel_gaussian = np.array([
[1, 2, 1],
[2, 4, 2],
[1, 2, 1]
], np.float32) / 16
img_gaussian = cv2.filter2D(img_gray, -1, kernel_gaussian)
cv2.imwrite(FILE_GAUSSIAN, img_gaussian)



実行結果

実行結果の画像です。3x3のフィルタは建物のエッジをシャープにとらえています。一方、5x5のフィルタは風景の大きな変化をとらえています。



               元画像



             グレースケール



           グラディエント フィルタ(3x3)



           グラディエント フィルタ(5x5)



             ハイパス フィルタ



           ラプラシアン フィルタ(3x3)



           ラプラシアン フィルタ(5x5)



             ガウシアン フィルタ