Main Content

균일하지 않은 조도 수정 및 전경 객체 분석하기

이 예제에서는 분석 전 전처리 단계로 영상을 향상시키는 방법을 보여줍니다. 이 예제에서는 전경 객체(쌀의 낱알)를 쉽게 식별할 수 있도록 균일하지 않은 배경 조도를 수정하고 영상을 이진 영상으로 변환합니다. 그런 다음, 객체를 분석(예: 각 쌀알의 면적 구하기)하고 영상의 모든 객체에 대한 통계량을 계산할 수 있습니다.

영상 전처리하기

영상을 작업 공간으로 읽어 들입니다.

I = imread('rice.png');
imshow(I)

Figure contains an axes object. The axes object contains an object of type image.

배경 조도가 영상의 맨 아래쪽보다 가운데 부분에서 더 밝습니다. 배경 조도를 더 균일하게 만들기 위해 영상을 전처리합니다.

첫 번째 단계로, 모폴로지 열기를 사용하여 전경(쌀알)을 모두 제거합니다. 모폴로지 열기 연산은 구조 요소를 완전히 포함할 수 없는 크기가 작은 객체를 제거합니다. 쌀 한 알의 크기에 맞도록 원판 모양 구조 요소의 반지름을 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)

Figure contains an axes object. The axes object contains an object of type image.

원본 영상 I에서 배경 근사 영상 background를 뺀 후 결과 영상을 표시합니다. 원래 영상에서 조정된 배경 영상을 빼면 결과로 나타나는 영상의 배경은 균일하지만 분석하기에는 영상이 약간 어둡습니다.

I2 = I - background;
imshow(I2)

Figure contains an axes object. The axes object contains an object of type image.

imadjust를 사용하여 데이터의 낮은 명암 1%와 높은 명암 1%를 포화 처리하고 uint8형 동적 범위를 채울 만큼 명암 값을 확장합니다. 이를 통해 앞서 처리한 영상 I2의 대비가 향상됩니다.

I3 = imadjust(I2);
imshow(I3)

Figure contains an axes object. The axes object contains an object of type image.

imtophat를 사용하면 앞의 두 단계를 모두 거치지 않고 한 단계로 작업할 수 있습니다. 이 함수는 먼저 모폴로지 열기를 계산한 다음 원본 영상에서 모폴로지 열기가 수행된 영상을 뺍니다.

I2 = imtophat(I,strel('disk',15));

분석에 툴박스 함수를 사용할 수 있도록 처리된 영상을 이진화한 버전의 영상을 생성합니다. imbinarize 함수를 사용하여 회색조 영상을 이진 영상으로 변환합니다. bwareaopen 함수를 사용하여 영상에서 배경 잡음을 제거합니다.

bw = imbinarize(I3);
bw = bwareaopen(bw,50);
imshow(bw)

Figure contains an axes object. The axes object contains an object of type image.

영상에서 객체 식별하기

이제 원래 영상을 이진화한 버전이 있으므로 영상의 객체를 분석할 수 있습니다.

이진 영상에 있는 연결성분(객체)을 모두 찾습니다. 결과의 정확성은 객체 크기와 연결성 파라미터(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)

Figure contains an axes object. The axes object contains an object of type image.

레이블 행렬을 생성한 후 의사색상 인덱스 영상으로 표시하여 영상의 연결성분을 모두 시각화합니다.

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)

Figure contains an axes object. The axes object contains an object of type image.

면적 기반 통계량 계산하기

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)

Figure contains an axes object. The axes object contains an object of type image.

histogram 명령을 사용하여 쌀알 면적의 히스토그램을 생성합니다.

histogram(grain_areas)
title('Histogram of Rice Grain Area')

Figure contains an axes object. The axes object with title Histogram of Rice Grain Area contains an object of type histogram.

참고 항목

| | | | | | | | |