가버 필터를 사용한 텍스처 분할
이 예제에서는 텍스처 분할을 사용하여 영역의 텍스처를 기준으로 영역을 식별하는 방법을 보여줍니다. 목표는 화장실 바닥에서 개를 분할하는 것입니다. 화장실 바닥의 규칙적이고 주기적 패턴의 텍스처와 개털의 규칙적이고 부드러운 텍스처 간에는 차이가 있기 때문에 시각적으로 명확하게 분할할 수 있습니다.
가버 필터는 포유류 시각 체계의 단순 세포를 적절하게 모델링한 필터입니다. 이런 이유로 가버 필터는 사람이 텍스처를 구분하는 방식을 잘 보여주는 모델로 여겨지며, 따라서 텍스처 인식 알고리즘을 설계할 때 유용하게 사용할 수 있는 모델입니다.
입력 영상 읽어 들이기
입력 영상을 읽어 들여 표시합니다. 이 예제에서는 예제가 더 빠르게 실행될 수 있도록 영상의 크기를 축소합니다.
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);
이 예제에서는 가버 필터 뱅크의 각 필터마다 개별 특징이 있으며, 직전 단계에서 추가한 공간 정보의 특징 두 개가 더 있습니다. 모두 합치면 입력 영상의 각 픽셀마다 24개의 가버 특징과 2개의 공간 특징이 있습니다.
특징 세트 시각화하기
특징이 평균 0과 단위 분산을 갖도록 정규화합니다. 계산을 단순화하려면 먼저 특징 세트를 26개의 열을 갖는 2차원 행렬로 형태 변경합니다. 이 형식에서는 각 특징에 대해 하나의 열이 있게 되며, 평균 및 표준편차를 열 단위로 계산할 수 있습니다. 특징을 정규화한 후 행렬을 원래의 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 함수를 사용하여 특징 세트를 두 개의 군집으로 분할합니다. NormalizeInput 이름-값 인수를 true로 지정하여 각 특징을 개별적으로 정규화합니다. 목적 함수를 최소화할 때 국소 최솟값을 방지하기 위해 k-평균 군집화 과정을 다섯 번 반복합니다.
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]