ガボール フィルターを使用したテクスチャのセグメンテーション
この例では、テクスチャに基づいて領域を識別するためにテクスチャのセグメンテーションを使用する方法を示します。目標は犬と浴室の床をセグメント化することです。浴室の床の規則正しい周期パターンと犬の毛の均一で滑らかなテクスチャの違いにより、セグメンテーションは一目瞭然です。
ガボール フィルターは、哺乳類の視覚システムの単純細胞に対する合理的なモデルです。そのため、ガボール フィルターはヒトがテクスチャをどのように区別するかを示す優れたモデルと考えられており、その結果、テクスチャを認識するアルゴリズムを設計するうえで役立つモデルになります。
入力イメージの読み取り
入力イメージを読み取って表示します。この例では、実行を高速化するためにイメージを縮小しています。
A = imread("kobi.png");
A = imresize(A,0.25);
imshow(A)
ガボール フィルターの配列の設計
さまざまな周波数と方向に調整したガボール フィルターの配列を設計します [1]。周波数と方向の組み合わせは、多様なほぼ直交する、周波数と方向の情報のサブセットを入力イメージで局所的に使うように設計されています。方向は、0 度から 135 度まで 45 度刻みでサンプリングします。波長は、4/sqrt(2) から入力イメージの斜辺の長さまで 2 のべき乗で増加させながらサンプリングします。
[numRows,numCols,~] = size(A); wavelengthMin = 4/sqrt(2); wavelengthMax = hypot(numRows,numCols); n = floor(log2(wavelengthMax/wavelengthMin)); wavelength = 2.^(0:(n-2)) * wavelengthMin; deltaTheta = 45; orientation = 0:deltaTheta:(180-deltaTheta); g = gabor(wavelength,orientation);
ガボール振幅応答の計算
imgaborfilt 関数を使用して、ソース イメージからガボール フィルターの振幅応答を計算します。ガボール振幅応答は、"ガボール エネルギー" と呼ばれることもあります。gabormag(:,:,ind) 内の各ガボール振幅応答は、グレースケールのソース イメージに適用された対応するガボール フィルター g(ind) の出力です。
Agray = im2gray(A); gabormag = imgaborfilt(Agray,g);
特徴セットの作成
分類に使用するためにガボール振幅応答を後処理します。この後処理には、ガウス平滑化と特徴セットへの追加的な空間情報の追加が含まれます。
各ガボール振幅応答には、良好にセグメント化された一定テクスチャの領域内でも、いくつかの局所的なばらつきが含まれています。これらの局所的なばらつきによってセグメンテーションの精度が損なわれます。ガウス ローパス フィルターを使用してガボール振幅情報を平滑化することで、これらのばらつきを補正します。各ガボール振幅応答に異なるガウス フィルターを適用して、各ガウス フィルターの標準偏差が、対応する応答を生成したガボール フィルターの波長と一致するようにします。平滑化項 K を使用して、ガボール振幅応答に適用する平滑化の量を制御します。
K = 3; for i = 1:length(g) sigma = 0.5*g(i).Wavelength; gabormag(:,:,i) = imgaussfilt(gabormag(:,:,i),K*sigma); end
ガボール特徴セットを、X と Y の両方の空間位置情報のマップで補完します。この追加情報により、分類器は空間的に近接したグループを優先できるようになります。
X = 1:numCols; Y = 1:numRows; [X,Y] = meshgrid(X,Y); featureSet = cat(3,gabormag,X,Y);
この例には、ガボール フィルター バンクにある各フィルターの個別の特徴に加え、前の手順で追加した空間情報の 2 つの特徴が存在します。全体では、入力イメージのピクセルごとにガボールの特徴が 24 個、空間的な特徴が 2 個となります。
特徴セットの可視化
ゼロ平均、単位分散に特徴を正規化します。計算を簡略化するために、まず特徴セットを 26 列の 2 次元行列に再形成します。この形式では、特徴ごとに 1 つの列があり、平均と標準偏差の計算を列ごとに実行できます。特徴を正規化した後、行列を元の 3 次元形状に再形成します。
X = reshape(featureSet,numRows*numCols,[]); Xnorm = (X-mean(X))./std(X); featureSetNorm = reshape(Xnorm,numRows,numCols,[]);
正規化された特徴をモンタージュとして表示します。
montage(featureSetNorm,[],Size=[5 6],Background="w")
特徴の分類
imsegkmeans 関数を使用して、特徴セットを 2 つのクラスターに分割します。名前と値の引数 NormalizeInput を true として指定し、各特徴を個別に正規化します。目的関数を最小化する際の局所最小値を回避するために、k-means クラスタリング プロセスを 5 回繰り返します。
featureSet = im2single(featureSet); L = imsegkmeans(featureSet,2,NormalizeInput=true,NumAttempts=5);
labeloverlay を使用して、イメージの上にセグメンテーション ラベルを表示します。
imshow(labeloverlay(A,L))

ラベル行列 L に関連付けられたマスク BW から作成される前景と背景のイメージを確認します。
Aseg1 = zeros(size(A),"like",A); Aseg2 = zeros(size(A),"like",A); BW = L == 2; BW = repmat(BW,[1 1 3]); Aseg1(BW) = A(BW); Aseg2(~BW) = A(~BW); montage({Aseg1,Aseg2});

参照
[1]