0
0

空間フィルター

Posted at

空間フィルター

空間の情報は直線、カーブする曲線、円や四角など形を表す情報である。このような形を取り出す方法として、空間フィルターという画像処理がある。
フィルターは2次元の行列で表し、画像の一部とフィルターの要素の積の和を、画像をスライドさせながら画像の現領域で求めていく。このような計算を畳み込み演算と呼ぶ。

元画像の位置(i, j)のピクセル値をx(i, j)、3×3のフィルターをh(i, j)としたら、畳み込み演算でえられる値g(i, j)は、以下のようになる。

g(i, j) = \sum_{u=-1}^{1} \sum_{v=-1}^{1} x(i + u, j + v) h(u + 1, v + 1)

フィルターの大きさは3×3だけでなく任意に決めることができるが、5×5、7×7など、中心を決められる奇数の幅が使いやすい。
実際に手書き数字に畳み込み演算をしてみる。

import numpy as np
import matplotlib.pyplot as plt
import time

from keras.datasets import mnist
from keras.utils import to_categorical

from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam

(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(60000, 28, 28, 1)
x_train = x_train.astype('float32')
x_train = x_train / 255

num_classes = 10

y_train = to_categorical(y_train, num_classes)

x_test = x_test.reshape(10000, 28, 28, 1)
x_test = x_test.astype('float32')
x_test = x_test / 255

y_test = to_categorical(y_test, num_classes)

id_img = 2
myfile1 = np.array([[1, 1, 1], [1, 1, 1], [-2, -2, -2]], dtype=float)
myfile2 = np.array([[-2, 1, 1], [-2, 1, 1], [-2, 1, 1]], dtype=float)

x_img = x_train[id_img, :, :, 0]
img_h = 28
img_w = 28

x_img = x_img.reshape(img_h, img_w)

out_img1 = np.zeros_like(x_img)
out_img2 = np.zeros_like(x_img)

# フィルター処理
for ih in range(img_h - 3):
    for iw in range(img_w - 3):
        img_part = x_img[ih:ih + 3, iw:iw + 3]
        out_img1[ih + 1, iw + 1] = np.dot(img_part.reshape(-1), myfile1.reshape(-1))
        out_img2[ih + 1, iw + 1] = np.dot(img_part.reshape(-1), myfile2.reshape(-1))

# 表示
plt.figure(1, figsize=(12, 3.2))
plt.subplots_adjust(wspace=0.5)
plt.gray()

plt.subplot(1, 3, 1)
plt.pcolor(1 - x_img)
plt.xlim(-1, 29)
plt.ylim(29, -1)

plt.subplot(1, 3, 2)
plt.pcolor(-out_img1)
plt.xlim(-1, 29)
plt.ylim(29, -1)

plt.subplot(1, 3, 3)
plt.pcolor(-out_img2)
plt.xlim(-1, 29)
plt.ylim(29, -1)

plt.show()

image.png

左画像が元の画像であり、真ん中は横ラインにエッジを効かせた画像。右は縦ラインにエッジを効かせた画像である。

フィルターを適用すると出力画像のサイズは一回り小さくなる。この対応策としてパディングという方法がある。

パディングはフィルターを適用する前に、0などの固定した要素で周囲を水増しする方法である。
3×3のフィルターを適用する場合には、幅1のパディングを施、5×5の場合には、幅2のパディングをすればいい。

パディングに加えてフィルター処理に関するパラメータがもう1つある。フィルターは1つ間隔をずらすが、2でも3でも、任意の間隔でずらすことができる。この間隔をストライド呼ぶ。
ストライドを大きくすると出力画像は小さくなる。パディングやストライドの値はライブラリで畳み込みネットワークを使う際に、引数として渡すことになる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0