OpenCVによる2次元ガボールフィルター作成

  • URLをコピーしました!

こんにちは。

「ガボール・パッチ」「ガボール・アイ」を聞いた事はありますか?Wikiにあるのは、こんなもわーっとした気持ち悪い画像です。

ガボールフィルタによって作成された模様ですが視力回復に効果的という事で有名です。視力回復用の本も出版されているので、たまにこの本で近視・老眼予防をしています。ただ、効果のほどは、ほんとによくわかりません。。もっと気が向いた時じゃなくて毎日何分とかでやらないと難しいですよね。このガボールパッチがなぜ視力回復に効果的かというと、医者ではありませんので、正確にはお伝えできてないかもしれません。。一応、「一次視覚皮質のニューロンが受容野構造と形がマッチした刺激ほど強く反応し、ガボールパッチがそれに一致する特性を持っている」という事らしいです。

そして、ガボールフィルタはエッジ検出、テクスチャ解析、特徴抽出等、画像処理アプリケーションで使用されています。OpenCVでは「getGaborKernel」で使えるのですが、パラメータの何を触ったらどう変わるのか解説をしていきます。

目次

getGaborKernelのパラメータ

retval = cv.getGaborKernel(ksize, sigma, theta, lambd, gamma[, psi[, ktype]])

ksizeガボールフィルタのサイズ(n,n)
sigmaガウシアン包絡線の標準偏差
thetaガボール関数の平行縞に対する法線の向き
lambd正弦波因子の波長
gamma空間アスペクト比
psi位相オフセット
ktypeフィルタ係数の種類.CV_32F または CV_64F

パラメータ:sigma

sigmaを増やすと、ガボール関数のストライプの数が増えます。

パラメータ:theta

thetaはフィルタの向きが変わります。0度は垂直です。

パラメータ:lambd

lambdはガボール関数のストリップの幅です。

パラメータ:gamma

gammaは空間アスペクト比です。数値が高いほど楕円率が高くなります。(細長くなる)

オプションパラメータ:psi

psiは正弦波の位相オフセットです。0にすると波の高い位置が中心に来ます。

ソースコード

# sigma
axes=[]
fig=plt.figure()
t = 'ksize=(100,100), theta=0, lambd=10, gamma=0.5, psi=0'
fig.text(0.2, 0.1, t ,wrap=True)

lstSigma = [4,8,12]
for i, sigma in enumerate(lstSigma):
    gabor = cv2.getGaborKernel(ksize=(100,100), sigma=sigma, theta=0, lambd=10, gamma=0.5, psi=0)

    axes.append( fig.add_subplot(1, len(lstSigma), i+1) )
    subplot_title=("sigma="+str(sigma))
    axes[-1].set_title(subplot_title)

    plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
    plt.tick_params(bottom=False,left=False,right=False,top=False)
    plt.imshow(gabor,cmap="gray")

fig.tight_layout()
fig.savefig("image_sigma.png")

plt.show(block=True)


# lambd
axes=[]
fig=plt.figure()
t = 'ksize=(100,100), sigma=8, theta=0, gamma=0.5, psi=0'
fig.text(0.2, 0.1, t ,wrap=True)

lstLambd = [4,8,12]
for i, lambd in enumerate(lstLambd):
    gabor = cv2.getGaborKernel(ksize=(100,100), sigma=8, theta=0, lambd=lambd, gamma=0.5, psi=0)

    axes.append( fig.add_subplot(1, len(lstLambd), i+1) )
    subplot_title=("lambd="+str(lambd))
    axes[-1].set_title(subplot_title)

    plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
    plt.tick_params(bottom=False,left=False,right=False,top=False)
    plt.imshow(gabor,cmap="gray")

fig.tight_layout()
fig.savefig("image_lambd.png")

plt.show(block=True)


# theta
axes=[]
fig=plt.figure()
t = 'ksize=(100,100), sigma=8, lambd=10, gamma=0.5, psi=0'
fig.text(0.2, 0.1, t ,wrap=True)

lstTheta = [0,45,90]
for i, theta in enumerate(lstTheta):
    gabor = cv2.getGaborKernel(ksize=(100,100), sigma=8, theta=numpy.radians(theta), lambd=10, gamma=0.5, psi=0)

    axes.append( fig.add_subplot(1, len(lstTheta), i+1) )
    subplot_title=("theta="+str(theta))
    axes[-1].set_title(subplot_title)

    plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
    plt.tick_params(bottom=False,left=False,right=False,top=False)
    plt.imshow(gabor,cmap="gray")

fig.tight_layout()
fig.savefig("image_theta.png")

plt.show(block=True)

# gamma
axes=[]
fig=plt.figure()
t = 'ksize=(100,100), sigma=8, theta=0, lambd=10, psi=0'
fig.text(0.2, 0.1, t ,wrap=True)

lstGamma = [0.5,0.75,1]
for i, gamma in enumerate(lstGamma):
    gabor = cv2.getGaborKernel(ksize=(100,100), sigma=8, theta=0, lambd=10, gamma=gamma, psi=0)

    axes.append( fig.add_subplot(1, len(lstGamma), i+1) )
    subplot_title=("gamma="+str(gamma))
    axes[-1].set_title(subplot_title)

    plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
    plt.tick_params(bottom=False,left=False,right=False,top=False)
    plt.imshow(gabor,cmap="gray")

fig.tight_layout()
fig.savefig("image_gamma.png")

plt.show(block=True)

# psi
axes=[]
fig=plt.figure()
t = 'ksize=(100,100), sigma=8, theta=0, lambd=10, gamma=0.5'
fig.text(0.2, 0.1, t ,wrap=True)

lstPsi = [0,1,1.5]
for i, psi in enumerate(lstPsi):
    gabor = cv2.getGaborKernel(ksize=(100,100), sigma=8, theta=0, lambd=10, gamma=0.5, psi=psi)

    axes.append( fig.add_subplot(1, len(lstPsi), i+1) )
    subplot_title=("psi="+str(psi))
    axes[-1].set_title(subplot_title)

    plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
    plt.tick_params(bottom=False,left=False,right=False,top=False)
    plt.imshow(gabor,cmap="gray")

fig.tight_layout()
fig.savefig("image_psi.png")

plt.show(block=True)
  • URLをコピーしました!

コメント

コメント一覧 (2件)

  • こんにちは、初めて書かせていただきます。
    getGaborKernel()のパラメータksizeですが、
    この指定は奇数の方が良いのではないでしょうか?
    getGaborKernel()関数側が適切に偶数サイズ指定でも
    奇数に丸めてくれるので、このことを知っていれば
    問題ないとは思います。

    • SitarHarmonics さま
      コメントありがとうございます。大変遅くなりまして申し訳ありませんでした。
      ご指摘ありがとうございます!ksizeが奇数が望ましいという事について、知りませんでした。多くの畳み込み層フィルターサイズは基本的に奇数なので、奇数が望ましいという文献を見ました。ありがとうございます。

      奇数がなぜ望ましいのか解説されていたサイト↓
      https://qr.paps.jp/j8nTI

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次