テクスチャの認識
次の問題どのように解きますか?
もちろん人間が見れば④番だというのはすぐにわかりますが、AI(プログラム)を使ってやろうとすると少し考える必要があります。いろいろなやり方はあるかと思いますが、軽量で低コストなLocalBinaryPatternを使ったやり方を紹介します。
Local Binary Patternとは
1994年にフィンランドにあるオウル大学のT.Ojalaさん達によって提案1された特徴量です。LocalBinaryPattern(LBP)はその名前のとおり、画像の局所的な表現を特徴量としたもので、各画素を周囲の近傍画素と比較した相対値で構成されています。演算コストが低くて、画像の濃淡値の変動に強いといった特徴があり、1994年の最初の提案以降もいろいろな改良が加えられています。特に非ディープラーニング系では、顔画像認識や画像検索やテクスチャ分割、および動画像解析など幅広く使用されています。
LBP特徴量の求め方
LBP特徴量を画像から抽出するための手順を説明します。
まずはバイナリ化です。画像をグレースケール化して、その画像の各ピクセルについて中心ピクセルを囲む8近傍を選択します。
中心のピクセル(56のピクセル)を取り、それをその近傍8ピクセルに対して閾値として設定します。 中心ピクセルの値より隣接ピクセルの値の方が大きいか等しい場合1に、小さい場合は0に設定します。
次に、LBP値を計算します。真ん中上の点から反時計回りに2進数として解釈して、それを10進数に直します。この例では49になります。
これを入力画像の全てのピクセルに対して行うので、計算されたLBP値は、元の画像と同じ幅と高さの出力配列として得られます。
LBP値は最小値が0で最大値が255になるので、グレースケールの画像として可視化する事もできます。下の図は、画像をLBP値にしてグレースケール化したものになります。
また、LBP値は中心値と周辺値との大小比較でしかないため、原理的に濃淡に対して不変性が保たれます。下の例は入力画像の露出値を変更して暗くしたものです。それに対してLBP値のグレースケール画像の方はほとんど変化してないのがわかるかと思います。
最後に、LBP値を特徴量として扱いやすくするためにヒストグラム化します。LBP値は0〜255の256段階あるので、各値の出現頻度を256binのヒストグラムとして構築する事ができます。
このヒストグラムを正規化すれば、256次元で長さ1の特徴ベクトルとして扱うことができます。
Uniform LBP
ここまでの説明では、3x3の画像範囲で256段階固定となっていましたが、もっと柔軟に画像パターンを捉えることができるように、これらの値をパラメータ化する拡張が提案2されました。パラメータは次の2つです。
- パラメータ $P$: 円形で対称な近傍の点の数
- パラメータ $R$: 円の半径
また、回転すると一致するパターンは1つに集約し、画像の回転に対してもロバストになる改良も加えられました。下の例3では、8つのマスクパターンを最も左のLBP値15に集約しています。
さらに、回転させたら同じ形となるパターンのうち、意味をなすもの同士を集約するために、Uniformパターンという考え方が導入されました。下の図3は円を順番になぞっていった場合の 0 → 1 もしくは、1 → 0 の遷移回数毎にまとめたものです。$U=0$は遷移回数0回、$U=2$は遷移回数2回となります。このように$U$の値ごとにパターンをまとめ、$U=0$もしくは$U=2$となるのものをUniformパターン、それ以外のものを non-uniformパターンと定義します。
$P=8$で考えた場合、Uniformパターンとなるものは全部で58種類あり、そのうち回転して同じとなるものを同一パターンに集約すればUniformパターンは下の図3のように9種類に分けられます。non-uniformパターンを全てまとめて1種類に集約すれば、全てのパターンは10種類のいずれかに分類できることになります。
この例のように$P=8$の場合は10種類となりますが、この種類数は$P$にのみ依存するので、点の数が$P$の場合$(P+2)$種類に分類できるというように一般化することができます。
Uniformパターンは点の数によって種類が分けられますが、それぞれのUniformパターンは画像内の特定の箇所でよく出現することがわかっています。例えば$P=8$の場合は下図3のようになります。
次の図4はタイルの画像をUniformLBPにして、そのパターン出現頻度をヒストグラム化したものです。ヒストグラムの赤色の部分は画像の赤色の部分で検出されています。Uniformパターン毎に画像内の違う特定の箇所で検出されているというのがよくわかるかと思います。
LBPの実装
実際にLBPを利用するには、pipでscikit-imageをインストールすればOKで、LBP値を取得する部分は一行で書くことができます。次のコードは$P=22$、$R=9$でUniformLBPを取得してヒストグラム化する例になります。
import cv2
from skimage import feature
from matplotlib import pyplot as plt
file_name = './tex/sample1.jpg'
bgr_img = cv2.imread(file_name)
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
points = 22
radius = 9
# compute the Local Binary Pattern representation of the image
lbp = feature.local_binary_pattern(gray_img, points, radius, method='uniform')
plt.hist(lbp.ravel(), bins=points + 2, range=(0, points + 2), color='red')
plt.show()
このコードを実行した結果、下記のヒストグラムが出力されます。
LBPの実験
6つの写真を使って実験してみます。
同じ種類のテクスチャを2枚ずつ合計6つの異なる写真に対して、UniformLBPで(non-uniformパターンを除いて)ヒストグラムにした結果になります。
結果のヒストグラムを見ると、同じ種類のテクスチャはヒストグラムの形が似ているのがわかると思います。ヒストグラムを特徴ベクトルにして、例えばcos類似度などで比較すれば簡単に同じオブジェクトを見つける事ができるかと思います。
-
Ojala T, Pietikäinen M & Harwood D, “Performance evaluation of texture measures with classification based on Kullback discrimination of distributions.”, Proc. 12th International Conference on Pattern Recognition (ICPR 1994), Jerusalem, Israel. Vol I, 582-585. (1994) ↩
-
Ojala T, Pietikäinen M & Mäenpää T (2002) Multiresolution gray-scale and rotation invariant texture classification with Local Binary Patterns. IEEE Transactions on Pattern Analysis and Machine Intelligence 24(7):971-987. ↩
-
http://www.ee.oulu.fi/research/imag/mvg/files/pdf/CVPR-tutorial-final.pdf ↩ ↩2 ↩3 ↩4
-
http://scikit-image.org/docs/dev/auto_examples/features_detection/plot_local_binary_pattern.html ↩