Hello Wor.log

IT系大学生4人による備忘録のようなもの

opencvでガボールフィルタ(python)

CPPXのXです。

opencvを使ってガボールフィルタをかけたいと思います。

環境

import

importするものを先に書いておきます。

import pylab
import numpy
import cv2

サクッとフィルタをかけてみる

img = cv2.imread("画像のpath") # pathを間違えるとNoneが返ってきます
gabor = cv2.getGaborKernel((30, 30), 4.0, numpy.radians(0), 10, 0.5, 0)
dst = cv2.filter2D(img, -1, gabor)
pylab.imshow(dst) and pylab.show()

フィルタを作成して、それを画像に対して演算する流れです。

画像はお好きな画像で大丈夫です。
上記を実行すると、画像中の縦線が抽出されるかなと思います。

ガボールフィルタは向きを持ったフィルタです。
このフィルタを適用すると、画像中の特定の線を検出する事ができます。

ガボールフィルタに関しては、以下の記事で分かりやすく説明されていました。

zellij.hatenablog.com

本記事では、opencvガボールフィルタを作成する際に、パラメータをいじったらどのようにフィルタが変化するかを説明していきます。

フィルタを眺める

生成されたフィルタがどのような状態なのか確認したいと思います。

gabor = cv2.getGaborKernel((30, 30), 4.0, numpy.radians(0), 10, 0.5, 0)
pylab.imshow(gabor, cmap="gray") and pylab.show()

このようにしてフィルタを確認する事ができます。
以下、フィルタの結果画像はこのようにして確認したものを貼っていきます。

パラメータの説明

パラメータを変更する事でどのようにフィルタが変化するか見ていきます。

省いている箇所は以下と同じパラメータを使っています。

cv2.getGaborKernel((30, 30), 4.0, numpy.radians(0), 10, 0.5, 0)

1つめ ksize

これを変更するとフィルタのサイズが変わります。

....getGaborKernel((30, 30), .... f:id:cppx:20171202160116p:plain

....getGaborKernel((100, 100), .... f:id:cppx:20171202160226p:plain

2つめ sigma

これを変更すると波が出てくる範囲が広がります。

....getGaborKernel((100, 100), 4, .... f:id:cppx:20171202160226p:plain

....getGaborKernel((100, 100), 16, .... f:id:cppx:20171202160850p:plain

3つめ theta

これを変更するとフィルタの向きが変わります。
指定した角度に直角に交わる線が検出されます。

弧度法で指定します。
ので、今回はnumpy.radiansを使って度数法から変換しています。

....getGaborKernel((100, 100), 16, numpy.radians(0), .... f:id:cppx:20171202160850p:plain

....getGaborKernel((100, 100), 16, numpy.radians(45), .... f:id:cppx:20171202161346p:plain

4つめ lambd

これを変更すると波長が変わります。

....getGaborKernel((100, 100), 16, numpy.radians(45), 10, .... f:id:cppx:20171202161346p:plain

....getGaborKernel((100, 100), 16, numpy.radians(45), 40, .... f:id:cppx:20171202161638p:plain

5つめ gamma

これを変更すると直角方向の広がり方が変わります。

....getGaborKernel((100, 100), 16, numpy.radians(45), 40, 0.5, .... f:id:cppx:20171202161638p:plain

....getGaborKernel((100, 100), 16, numpy.radians(45), 40, 1, .... f:id:cppx:20171202162917p:plain

オプション psi

これを変更すると位相が変わります。

0を指定すると、波のてっぺんが真ん中にくるので、0にしておくといいです。

....getGaborKernel((100, 100), 16, numpy.radians(45), 40, 1, 0).... f:id:cppx:20171202162917p:plain

....getGaborKernel((100, 100), 16, numpy.radians(45), 40, 1, 1.5).... f:id:cppx:20171202163724p:plain

オプション ktype

これを変更するとデータの型が変わります。

gabor = cv2.getGaborKernel((100, 100), 16, numpy.radians(45), 40, 1, 1.5, cv2.CV_32F)
print(gabor.dtype) # => float32
gabor = cv2.getGaborKernel((100, 100), 16, numpy.radians(45), 40, 1, 1.5, cv2.CV_64F)
print(gabor.dtype) # => float64

終わり

簡易的な説明を見たい場合は、以下を実行するとドキュメントが見れます。

help(cv2.getGaborKernel)

この関数に限らず、ドキュメントは用意されてる事が多いので、困ったらhelpを見ると幸せ度数が上昇するので、覚えておくといいかもしれません。