텍스처 필터를 사용한 텍스처 분할
이 예제에서는 텍스처를 기준으로 영역을 식별하고 분할하는 방법을 보여줍니다.
영상 읽어 들이기
가방의 텍스처 패턴인 회색조 영상을 읽어 들이고 표시합니다.
I = imread('bag.png'); imshow(I) title('Original Image')
텍스처 영상 만들기
entropyfilt
를 사용하여 텍스처 영상을 만듭니다. 함수 entropyfilt
는 배열을 반환합니다. 여기서 각 출력 픽셀은 입력 영상 I
의 해당 픽셀 주변의 9×9 이웃에 있는 엔트로피 값을 포함합니다. 엔트로피는 임의성에 대한 통계적 측정값입니다.
stdfilt
및 rangefilt
를 사용하여 비슷한 분할 결과를 얻을 수도 있습니다. 국소 엔트로피의 텍스처 영상과 비교하기 위해 국소 표준편차를 표시하는 텍스처 영상 S
와 국소 범위를 표시하는 텍스처 영상 R
을 만듭니다.
E = entropyfilt(I); S = stdfilt(I,ones(9)); R = rangefilt(I,ones(9));
rescale
을 사용하여 텍스처 영상 E
와 S
를 다시 스케일링하여 픽셀 값의 범위를 double
데이터형 영상에서 요구되는 [0, 1] 이내로 만듭니다.
Eim = rescale(E); Sim = rescale(S);
3개의 텍스처 영상을 몽타주에 표시합니다.
montage({Eim,Sim,R},'Size',[1 3],'BackgroundColor','w',"BorderSize",20) title('Texture Images Showing Local Entropy, Local Standard Deviation, and Local Range')
하단 텍스처의 마스크 만들기
여기서는 앞의 예제를 계속 사용해서 엔트로피 텍스처 영상 Eim
을 처리해 보겠습니다. 나머지 두 유형의 텍스처 영상도 다른 모폴로지 함수로 비슷한 과정을 반복하면 비슷한 분할 결과를 얻을 수 있습니다.
다시 스케일링한 영상 Eim
을 텍스처 분할을 위해 이진화합니다. 두 텍스처의 경계에 있는 픽셀의 대략적인 명암 값 0.8이 임계값으로 선택됩니다.
BW1 = imbinarize(Eim,0.8);
imshow(BW1)
title('Thresholded Texture Image')
이진 영상 BW1
에서 분할된 객체는 흰색입니다. BW1
과 I
를 비교하면, 상단 텍스처는 과도하게 분할(흰색 객체 중복)되었고 하단 텍스처는 거의 완벽하게 분할되었음을 알 수 있습니다. bwareaopen
을 사용하여 상단 텍스처에서 객체를 제거합니다.
BWao = bwareaopen(BW1,2000);
imshow(BWao)
title('Area-Opened Texture Image')
imclose
를 사용하여 BWao
에 있는 객체의 가장자리를 매끄럽게 만들고 열린 구멍을 메웁니다. entropyfilt
에서 사용된 것과 동일한 9×9 이웃을 지정합니다.
nhood = ones(9);
closeBWao = imclose(BWao,nhood);
imshow(closeBWao)
title('Closed Texture Image')
imfill
을 사용하여 closeBWao
에 있는 객체의 구멍을 메웁니다. 마스크가 영상 맨 아래까지 미치지 않았기 때문에 하단 텍스처에 대해서는 이 마스크가 완벽하지 않습니다. 그러나 이 마스크를 사용하여 텍스처를 분할할 수는 있습니다.
mask = imfill(closeBWao,'holes'); imshow(mask); title('Mask of Bottom Texture')
마스크를 사용하여 텍스처 분할하기
텍스처를 서로 다른 두 개의 영상으로 분리합니다.
textureTop = I; textureTop(mask) = 0; textureBottom = I; textureBottom(~mask) = 0; montage({textureTop,textureBottom},'Size',[1 2],'BackgroundColor','w',"BorderSize",20) title('Segmented Top Texture (Left) and Segmented Bottom Texture (Right)')
분할 결과 표시하기
마스크가 false
인 곳에서는 레이블이 1이고 마스크가 true
인 곳에서는 레이블이 2인 레이블 행렬을 만듭니다. 원본 영상 위에 레이블 행렬을 겹쳐 놓습니다.
L = mask+1;
imshow(labeloverlay(I,L))
title('Labeled Segmentation Regions')
두 텍스처 간 경계의 윤곽선을 녹청색으로 표시합니다.
boundary = bwperim(mask); imshow(labeloverlay(I,boundary,"Colormap",[0 1 1])) title('Boundary Between Textures')
참고 항목
entropyfilt
| bwareaopen
| imclose
| imbinarize
| imfill
| bwperim
| rangefilt