균일하지 않은 조도 수정 및 전경 객체 분석하기
이 예제에서는 분석 전 전처리 단계로 영상을 향상시키는 방법을 보여줍니다. 이 예제에서는 전경 객체(쌀의 낱알)를 쉽게 식별할 수 있도록 균일하지 않은 배경 조도를 수정하고 영상을 이진 영상으로 변환합니다. 그런 다음, 객체를 분석(예: 각 쌀알의 면적 구하기)하고 영상의 모든 객체에 대한 통계량을 계산할 수 있습니다.
영상 전처리하기
영상을 작업 공간으로 읽어 들입니다.
I = imread('rice.png');
imshow(I)
배경 조도가 영상의 맨 아래쪽보다 가운데 부분에서 더 밝습니다. 배경 조도를 더 균일하게 만들기 위해 영상을 전처리합니다.
첫 번째 단계로, 모폴로지 열기를 사용하여 전경(쌀알)을 모두 제거합니다. 모폴로지 열기 연산은 구조 요소를 완전히 포함할 수 없는 크기가 작은 객체를 제거합니다. 쌀 한 알의 크기에 맞도록 원판 모양 구조 요소의 반지름을 15로 정의합니다.
se = strel('disk',15)
se = strel is a disk shaped structuring element with properties: Neighborhood: [29x29 logical] Dimensionality: 2
모폴로지 연산을 수행하려면 imopen
을 구조 요소와 함께 사용하십시오.
background = imopen(I,se); imshow(background)
원본 영상 I
에서 배경 근사 영상 background
를 뺀 후 결과 영상을 표시합니다. 원래 영상에서 조정된 배경 영상을 빼면 결과로 나타나는 영상의 배경은 균일하지만 분석하기에는 영상이 약간 어둡습니다.
I2 = I - background; imshow(I2)
imadjust
를 사용하여 데이터의 낮은 명암 1%와 높은 명암 1%를 포화 처리하고 uint8
형 동적 범위를 채울 만큼 명암 값을 확장합니다. 이를 통해 앞서 처리한 영상 I2
의 대비가 향상됩니다.
I3 = imadjust(I2); imshow(I3)
imtophat
를 사용하면 앞의 두 단계를 모두 거치지 않고 한 단계로 작업할 수 있습니다. 이 함수는 먼저 모폴로지 열기를 계산한 다음 원본 영상에서 모폴로지 열기가 수행된 영상을 뺍니다.
I2 = imtophat(I,strel('disk',15));
분석에 툴박스 함수를 사용할 수 있도록 처리된 영상을 이진화한 버전의 영상을 생성합니다. imbinarize
함수를 사용하여 회색조 영상을 이진 영상으로 변환합니다. bwareaopen
함수를 사용하여 영상에서 배경 잡음을 제거합니다.
bw = imbinarize(I3); bw = bwareaopen(bw,50); imshow(bw)
영상에서 객체 식별하기
이제 원래 영상을 이진화한 버전이 있으므로 영상의 객체를 분석할 수 있습니다.
이진 영상에 있는 연결성분(객체)을 모두 찾습니다. 결과의 정확성은 객체 크기와 연결성 파라미터(4, 8 또는 임의 값)에 따라, 그리고 서로 닿는 객체가 있는지(이 경우 하나의 객체로 레이블이 지정될 수 있음)에 따라 달라집니다. 이진 영상 bw
를 보면 일부 쌀알이 서로 닿아 있습니다.
cc = bwconncomp(bw,4)
cc = struct with fields:
Connectivity: 4
ImageSize: [256 256]
NumObjects: 95
PixelIdxList: {1x95 cell}
cc.NumObjects
ans = 95
영상에서 레이블이 50으로 지정된 쌀알을 표시합니다.
grain = false(size(bw)); grain(cc.PixelIdxList{50}) = true; imshow(grain)
레이블 행렬을 생성한 후 의사색상 인덱스 영상으로 표시하여 영상의 연결성분을 모두 시각화합니다.
labelmatrix
를 사용하여 bwconncomp
의 출력값에서 레이블 행렬을 만듭니다. labelmatrix
는 객체 수에 필요한 가장 작은 숫자형 클래스에 레이블 행렬을 저장합니다.
labeled = labelmatrix(cc);
whos labeled
Name Size Bytes Class Attributes labeled 256x256 65536 uint8
label2rgb
를 사용하여 컬러맵과 배경색을 선택하고 레이블 행렬의 객체가 컬러맵의 색에 매핑되는 방법을 선택합니다. 의사색상 영상에서는 레이블 행렬의 각 객체를 식별하는 레이블이 이에 연결된 컬러맵 행렬의 다른 색에 매핑됩니다.
RGB_label = label2rgb(labeled,'spring','c','shuffle'); imshow(RGB_label)
면적 기반 통계량 계산하기
regionprops
를 사용하여 영상에 있는 각 객체의 면적을 계산합니다. 각 쌀알은 cc
구조체에서 하나의 연결성분입니다.
graindata = regionprops(cc,'basic')
graindata=95×1 struct array with fields:
Area
Centroid
BoundingBox
각 쌀알의 면적 측정값을 포함할 새 벡터 grain_areas
를 만듭니다.
grain_areas = [graindata.Area];
50번째 성분의 면적을 구합니다.
grain_areas(50)
ans = 194
면적이 가장 작은 쌀알을 찾아 표시합니다.
[min_area, idx] = min(grain_areas)
min_area = 61
idx = 16
grain = false(size(bw)); grain(cc.PixelIdxList{idx}) = true; imshow(grain)
histogram
명령을 사용하여 쌀알 면적의 히스토그램을 생성합니다.
histogram(grain_areas)
title('Histogram of Rice Grain Area')
참고 항목
imopen
| bwareaopen
| bwconncomp
| regionprops
| imadjust
| imbinarize
| label2rgb
| labelmatrix
| imread
| imshow