Main Content

이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

딥러닝을 사용한 다중분광 영상의 의미론적 분할

이 예제에서는 3개의 색 채널, 3개의 근적외선 채널, 1개의 마스크로 구성된 7가지 채널로 다중분광 영상의 의미론적 분할을 수행하도록 U-Net 컨벌루션 신경망을 훈련시키는 방법을 보여줍니다.

이 예제에서는 U-Net 신경망을 훈련시키는 방법을 보여주고, 사전 훈련된 U-Net 신경망도 제공합니다. U-Net 신경망을 훈련시키려는 경우 CUDA 지원 NVIDIA™ GPU(Compute Capability 3.0 이상)를 사용하는 것이 권장됩니다(Parallel Computing Toolbox™가 필요함).

소개

의미론적 분할은 영상의 각 픽셀에 클래스 레이블을 지정하는 작업을 수반합니다. 의미론적 분할의 응용 사례 중 하나가 삼림 파괴 추적입니다. 즉 시간의 경과에 따른 산림 피복(forest cover)의 변화를 추적하는 것입니다. 환경 보호 기관은 어떤 지역의 환경 및 생태 건강을 평가하고 정량화하기 위해 삼림 파괴를 추적합니다.

딥러닝 기반의 의미론적 분할을 통해 고해상도 항공 사진에서 식생 피복을 정확히 측정할 수 있습니다. 한 가지 문제는 시각적 특성이 비슷한 클래스를 구별하는 것입니다. 이를테면 녹색 픽셀을 풀, 관목 또는 나무로 분류해야 합니다. 분류의 정확도를 높이기 위해 일부 데이터 세트는 각 픽셀에 대한 추가 정보를 제공해 주는 다중분광 영상을 포함하고 있습니다. 예를 들어, Hamlin Beach State Park 데이터 세트는 이 클래스를 더 확실하게 구별하도록 근적외선 채널로 컬러 영상을 보완합니다.

이 예제에서는 딥러닝 기반의 의미론적 분할 기법을 사용하여 다중분광 영상 세트로부터 어떤 지역의 식생 피복의 비율을 계산하는 방법을 보여줍니다.

데이터 다운로드하기

이 예제에서는 신경망 훈련에 고해상도 다중분광 데이터 세트를 사용합니다 [1]. 이 영상 세트는 뉴욕 햄린 비치 주립 공원 위에서 드론으로 촬영한 것입니다. 이 데이터에는 레이블이 지정된 훈련 세트, 검증 세트, 테스트 세트와 18가지 객체 클래스 레이블이 포함되어 있습니다. 데이터 파일의 크기는 최대 3.0GB입니다.

downloadHamlinBeachMSIData 헬퍼 함수를 사용하여 MAT 파일 버전의 데이터 세트를 다운로드합니다. 이 함수는 예제에 지원 파일로 첨부되어 있습니다.

imageDir = tempdir;
url = 'http://www.cis.rit.edu/~rmk6217/rit18_data.mat';
downloadHamlinBeachMSIData(url,imageDir);

또한 downloadTrainedUnet 헬퍼 함수를 사용하여 이 데이터셋에 대해 사전 훈련된 버전의 U-Net을 다운로드합니다. 이 함수는 예제에 지원 파일로 첨부되어 있습니다. 사전 훈련된 모델을 사용하면 훈련이 완료될 때까지 기다리지 않고 전체 예제를 실행할 수 있습니다.

trainedUnet_url = 'https://www.mathworks.com/supportfiles/vision/data/multispectralUnet.mat';
downloadTrainedUnet(trainedUnet_url,imageDir);

훈련 데이터 검사하기

데이터 세트를 작업 공간에 불러옵니다.

load(fullfile(imageDir,'rit18_data','rit18_data.mat'));

데이터의 구조를 확인합니다.

whos train_data val_data test_data
  Name            Size                         Bytes  Class     Attributes

  test_data       7x12446x7654            1333663576  uint16              
  train_data      7x9393x5642              741934284  uint16              
  val_data        7x8833x6918              855493716  uint16              

다중분광 영상 데이터는 채널 수x너비x높이 배열로 구성되어 있습니다. 그러나 MATLAB®에서는 다중채널 영상이 너비x높이x채널 수 배열로 구성됩니다. 데이터의 형태를 변경하여 채널을 3차원으로 만들려면 헬퍼 함수 switchChannelsToThirdPlane을 사용하십시오. 이 함수는 예제에 지원 파일로 첨부되어 있습니다.

train_data = switchChannelsToThirdPlane(train_data);
val_data   = switchChannelsToThirdPlane(val_data);
test_data  = switchChannelsToThirdPlane(test_data);

데이터가 올바른 구조인지 확인합니다.

whos train_data val_data test_data
  Name                Size                     Bytes  Class     Attributes

  test_data       12446x7654x7            1333663576  uint16              
  train_data       9393x5642x7             741934284  uint16              
  val_data         8833x6918x7             855493716  uint16              

RGB 컬러 채널은 3번째, 2번째, 1번째 영상 채널입니다. 훈련 영상, 검증 영상, 테스트 영상의 색 성분을 몽타주로 표시합니다. 영상이 화면에 더 밝게 표시되게 하려면 histeq 함수를 사용하여 히스토그램을 평활화하십시오.

figure
montage(...
    {histeq(train_data(:,:,[3 2 1])), ...
    histeq(val_data(:,:,[3 2 1])), ...
    histeq(test_data(:,:,[3 2 1]))}, ...
    'BorderSize',10,'BackgroundColor','white')
title('RGB Component of Training Image (Left), Validation Image (Center), and Test Image (Right)')

훈련 데이터의 마지막 3개 히스토그램 평활화 채널을 몽타주로 표시합니다. 이러한 채널은 근적외선 대역에 해당하며, 각각의 열 신호에 따라 영상의 각기 다른 성분을 강조 표시합니다. 예를 들어, 두 번째 채널 영상의 중심 근처에 있는 나무는 나머지 두 채널의 나무보다 더 세부적으로 표시됩니다.

figure
montage(...
    {histeq(train_data(:,:,4)), ...
    histeq(train_data(:,:,5)), ...
    histeq(train_data(:,:,6))}, ...
    'BorderSize',10,'BackgroundColor','white')
title('IR Channels 1 (Left), 2, (Center), and 3 (Right) of Training Image')

채널 7은 유효한 분할 지역을 나타내는 마스크입니다. 훈련 영상, 검증 영상, 테스트 영상을 위한 마스크를 표시합니다.

figure
montage(...
    {train_data(:,:,7), ...
    val_data(:,:,7), ...
    test_data(:,:,7)}, ...
    'BorderSize',10,'BackgroundColor','white')
title('Mask of Training Image (Left), Validation Image (Center), and Test Image (Right)')

레이블이 지정된 영상에는 분할을 위한 실측 데이터가 들어 있으며, 각 픽셀에 18개 클래스 중 하나가 지정되어 있습니다. 클래스 및 그 ID의 목록을 얻습니다.

disp(classes)
0. Other Class/Image Border      
1. Road Markings                 
2. Tree                          
3. Building                      
4. Vehicle (Car, Truck, or Bus)  
5. Person                        
6. Lifeguard Chair               
7. Picnic Table                  
8. Black Wood Panel              
9. White Wood Panel              
10. Orange Landing Pad           
11. Water Buoy                   
12. Rocks                        
13. Other Vegetation             
14. Grass                        
15. Sand                         
16. Water (Lake)                 
17. Water (Pond)                 
18. Asphalt (Parking Lot/Walkway)

클래스 이름의 벡터를 만듭니다.

classNames = [ "RoadMarkings","Tree","Building","Vehicle","Person", ...
               "LifeguardChair","PicnicTable","BlackWoodPanel",...
               "WhiteWoodPanel","OrangeLandingPad","Buoy","Rocks",...
               "LowLevelVegetation","Grass_Lawn","Sand_Beach",...
               "Water_Lake","Water_Pond","Asphalt"]; 

히스토그램을 평활화한 RGB 훈련 영상 위에 레이블을 겹쳐 놓습니다. 영상에 컬러바를 추가합니다.

cmap = jet(numel(classNames));
B = labeloverlay(histeq(train_data(:,:,4:6)),train_labels,'Transparency',0.8,'Colormap',cmap);

figure
title('Training Labels')
imshow(B)
N = numel(classNames);
ticks = 1/(N*2):1/N:1;
colorbar('TickLabels',cellstr(classNames),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none');
colormap(cmap)

훈련 데이터를 MAT 파일로, 훈련 레이블을 PNG 파일로 저장합니다.

save('train_data.mat','train_data');
imwrite(train_labels,'train_labels.png');

훈련을 위한 무작위 패치 추출 데이터저장소 만들기

무작위 패치 추출 데이터저장소를 사용하여 훈련 데이터를 신경망에 입력합니다. 이 데이터저장소는 실측 영상이 있는 영상 데이터저장소와 픽셀 레이블 데이터가 있는 픽셀 레이블 데이터저장소로부터 대응하는 여러 무작위 패치를 추출합니다. 패치는 대용량 영상으로 인한 메모리 부족을 방지하고 사용 가능한 훈련 데이터의 용량을 효과적으로 늘릴 수 있는 대표적인 기법입니다.

먼저 'train_data.mat'의 훈련 영상을 imageDatastore에 저장합니다. MAT 파일 형식은 비표준 영상 형식이므로 영상 데이터를 읽을 수 있도록 MAT 파일 리더를 사용해야 합니다. 헬퍼 MAT 파일 리더 matReader를 사용할 수 있습니다. 이 리더는 훈련 데이터의 첫 6개 채널을 추출하고 마스크가 포함된 마지막 채널은 생략합니다. 이 함수는 예제에 지원 파일로 첨부되어 있습니다.

imds = imageDatastore('train_data.mat','FileExtensions','.mat','ReadFcn',@matReader);

18개 레이블이 지정된 영역을 포함하는 레이블 패치를 저장하려면 pixelLabelDatastore (Computer Vision Toolbox)를 만드십시오.

pixelLabelIds = 1:18;
pxds = pixelLabelDatastore('train_labels.png',classNames,pixelLabelIds);

영상 데이터저장소 및 픽셀 레이블 데이터저장소로부터 randomPatchExtractionDatastore를 만듭니다. 각 미니 배치에는 256x256픽셀 크기의 패치 16개가 있습니다. Epoch 1회마다 1,000개의 미니 배치가 추출됩니다.

dsTrain = randomPatchExtractionDatastore(imds,pxds,[256,256],'PatchesPerImage',16000);

무작위 패치 추출 데이터저장소 dsTrain은 Epoch가 반복될 때마다 신경망으로 데이터의 미니 배치를 제공합니다. 데이터를 살펴보려면 데이터저장소를 미리 보십시오.

inputBatch = preview(dsTrain);
disp(inputBatch)
        InputImage        ResponsePixelLabelImage
    __________________    _______________________

    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 
    {256×256×6 uint16}     {256×256 categorical} 

U-Net 신경망 계층 만들기

이 예제에서는 변형된 U-Net 신경망을 사용합니다. U-Net에서는 초기 일련의 컨벌루션 계층의 사이에 일정 간격으로 최댓값 풀링 계층이 배치되어 입력 영상의 해상도를 연이어 낮춥니다. 그다음에 오는 일련의 컨벌루션 계층 사이에는 업샘플링 연산자가 여기저기 배치되어 입력 영상의 해상도를 연속적으로 높입니다 [2]. U-Net이라는 이름은 이 신경망을 문자 U와 같은 대칭 형태로 그릴 수 있다는 사실에서 유래했습니다.

이 예제에서는 컨벌루션에서 0으로 채우기를 사용하도록 U-Net을 수정합니다. 그러면 컨벌루션에 대한 입력 및 출력의 크기가 같아집니다. 몇 개의 사전 선택된 하이퍼파라미터가 있는 U-Net을 만들려면 헬퍼 함수 createUnet을 사용하십시오. 이 함수는 예제에 지원 파일로 첨부되어 있습니다.

inputTileSize = [256,256,6];
lgraph = createUnet(inputTileSize);
disp(lgraph.Layers)
  58x1 Layer array with layers:

     1   'ImageInputLayer'                        Image Input                  256x256x6 images with 'zerocenter' normalization
     2   'Encoder-Section-1-Conv-1'               Convolution                  64 3x3x6 convolutions with stride [1  1] and padding [1  1  1  1]
     3   'Encoder-Section-1-ReLU-1'               ReLU                         ReLU
     4   'Encoder-Section-1-Conv-2'               Convolution                  64 3x3x64 convolutions with stride [1  1] and padding [1  1  1  1]
     5   'Encoder-Section-1-ReLU-2'               ReLU                         ReLU
     6   'Encoder-Section-1-MaxPool'              Max Pooling                  2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     7   'Encoder-Section-2-Conv-1'               Convolution                  128 3x3x64 convolutions with stride [1  1] and padding [1  1  1  1]
     8   'Encoder-Section-2-ReLU-1'               ReLU                         ReLU
     9   'Encoder-Section-2-Conv-2'               Convolution                  128 3x3x128 convolutions with stride [1  1] and padding [1  1  1  1]
    10   'Encoder-Section-2-ReLU-2'               ReLU                         ReLU
    11   'Encoder-Section-2-MaxPool'              Max Pooling                  2x2 max pooling with stride [2  2] and padding [0  0  0  0]
    12   'Encoder-Section-3-Conv-1'               Convolution                  256 3x3x128 convolutions with stride [1  1] and padding [1  1  1  1]
    13   'Encoder-Section-3-ReLU-1'               ReLU                         ReLU
    14   'Encoder-Section-3-Conv-2'               Convolution                  256 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    15   'Encoder-Section-3-ReLU-2'               ReLU                         ReLU
    16   'Encoder-Section-3-MaxPool'              Max Pooling                  2x2 max pooling with stride [2  2] and padding [0  0  0  0]
    17   'Encoder-Section-4-Conv-1'               Convolution                  512 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    18   'Encoder-Section-4-ReLU-1'               ReLU                         ReLU
    19   'Encoder-Section-4-Conv-2'               Convolution                  512 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    20   'Encoder-Section-4-ReLU-2'               ReLU                         ReLU
    21   'Encoder-Section-4-DropOut'              Dropout                      50% dropout
    22   'Encoder-Section-4-MaxPool'              Max Pooling                  2x2 max pooling with stride [2  2] and padding [0  0  0  0]
    23   'Mid-Conv-1'                             Convolution                  1024 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    24   'Mid-ReLU-1'                             ReLU                         ReLU
    25   'Mid-Conv-2'                             Convolution                  1024 3x3x1024 convolutions with stride [1  1] and padding [1  1  1  1]
    26   'Mid-ReLU-2'                             ReLU                         ReLU
    27   'Mid-DropOut'                            Dropout                      50% dropout
    28   'Decoder-Section-1-UpConv'               Transposed Convolution       512 2x2x1024 transposed convolutions with stride [2  2] and cropping [0  0  0  0]
    29   'Decoder-Section-1-UpReLU'               ReLU                         ReLU
    30   'Decoder-Section-1-DepthConcatenation'   Depth concatenation          Depth concatenation of 2 inputs
    31   'Decoder-Section-1-Conv-1'               Convolution                  512 3x3x1024 convolutions with stride [1  1] and padding [1  1  1  1]
    32   'Decoder-Section-1-ReLU-1'               ReLU                         ReLU
    33   'Decoder-Section-1-Conv-2'               Convolution                  512 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    34   'Decoder-Section-1-ReLU-2'               ReLU                         ReLU
    35   'Decoder-Section-2-UpConv'               Transposed Convolution       256 2x2x512 transposed convolutions with stride [2  2] and cropping [0  0  0  0]
    36   'Decoder-Section-2-UpReLU'               ReLU                         ReLU
    37   'Decoder-Section-2-DepthConcatenation'   Depth concatenation          Depth concatenation of 2 inputs
    38   'Decoder-Section-2-Conv-1'               Convolution                  256 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    39   'Decoder-Section-2-ReLU-1'               ReLU                         ReLU
    40   'Decoder-Section-2-Conv-2'               Convolution                  256 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    41   'Decoder-Section-2-ReLU-2'               ReLU                         ReLU
    42   'Decoder-Section-3-UpConv'               Transposed Convolution       128 2x2x256 transposed convolutions with stride [2  2] and cropping [0  0  0  0]
    43   'Decoder-Section-3-UpReLU'               ReLU                         ReLU
    44   'Decoder-Section-3-DepthConcatenation'   Depth concatenation          Depth concatenation of 2 inputs
    45   'Decoder-Section-3-Conv-1'               Convolution                  128 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    46   'Decoder-Section-3-ReLU-1'               ReLU                         ReLU
    47   'Decoder-Section-3-Conv-2'               Convolution                  128 3x3x128 convolutions with stride [1  1] and padding [1  1  1  1]
    48   'Decoder-Section-3-ReLU-2'               ReLU                         ReLU
    49   'Decoder-Section-4-UpConv'               Transposed Convolution       64 2x2x128 transposed convolutions with stride [2  2] and cropping [0  0  0  0]
    50   'Decoder-Section-4-UpReLU'               ReLU                         ReLU
    51   'Decoder-Section-4-DepthConcatenation'   Depth concatenation          Depth concatenation of 2 inputs
    52   'Decoder-Section-4-Conv-1'               Convolution                  64 3x3x128 convolutions with stride [1  1] and padding [1  1  1  1]
    53   'Decoder-Section-4-ReLU-1'               ReLU                         ReLU
    54   'Decoder-Section-4-Conv-2'               Convolution                  64 3x3x64 convolutions with stride [1  1] and padding [1  1  1  1]
    55   'Decoder-Section-4-ReLU-2'               ReLU                         ReLU
    56   'Final-ConvolutionLayer'                 Convolution                  18 1x1x64 convolutions with stride [1  1] and padding [0  0  0  0]
    57   'Softmax-Layer'                          Softmax                      softmax
    58   'Segmentation-Layer'                     Pixel Classification Layer   Cross-entropy loss 

훈련 옵션 선택하기

SGDM(Stochastic Gradient Descent with Momentum: 모멘텀을 사용한 확률적 경사하강법)을 사용하여 신경망을 훈련시킵니다. trainingOptions (Deep Learning Toolbox) 함수를 사용하여 SGDM의 하이퍼파라미터 설정을 지정합니다.

심층 신경망을 훈련시키는 데는 상당한 시간이 소요됩니다. 학습률을 높게 지정하여 훈련 시간을 줄일 수 있습니다. 그러나 이렇게 하면 신경망의 기울기가 통제할 수 없을 만큼 증가하여 신경망이 성공적으로 훈련되지 않을 수 있습니다. 기울기를 유의미한 범위 내로 유지하기 위해 'GradientThreshold'의 값을 0.05로 설정하고 'GradientThresholdMethod'가 기울기의 L2-노름을 사용하도록 지정하여 기울기 제한을 활성화합니다.

initialLearningRate = 0.05;
maxEpochs = 150;
minibatchSize = 16;
l2reg = 0.0001;

options = trainingOptions('sgdm',...
    'InitialLearnRate',initialLearningRate, ...
    'Momentum',0.9,...
    'L2Regularization',l2reg,...
    'MaxEpochs',maxEpochs,...
    'MiniBatchSize',minibatchSize,...
    'LearnRateSchedule','piecewise',...    
    'Shuffle','every-epoch',...
    'GradientThresholdMethod','l2norm',...
    'GradientThreshold',0.05, ...
    'Plots','training-progress', ...
    'VerboseFrequency',20);

신경망 훈련시키기

훈련 옵션과 무작위 패치 추출 데이터저장소를 구성한 후에는 trainNetwork (Deep Learning Toolbox) 함수를 사용하여 U-Net 신경망을 훈련시킵니다. 신경망을 훈련시키려면 다음 코드의 doTraining 파라미터를 true로 설정하십시오. 훈련을 수행할 때는 CUDA 지원 NVIDIA™ GPU(Compute Capability 3.0 이상)를 사용하는 것이 권장됩니다.

다음 코드의 doTraining 파라미터를 false로 유지하면 이 예제는 사전 훈련된 U-Net 신경망을 반환합니다.

참고: 훈련은 NVIDIA™ Titan X에서 20시간 정도 걸리며, GPU 하드웨어에 따라 시간이 더 걸릴 수 있습니다.

doTraining = false; 
if doTraining
    modelDateTime = datestr(now,'dd-mmm-yyyy-HH-MM-SS');
    [net,info] = trainNetwork(dsTrain,lgraph,options);
    save(['multispectralUnet-' modelDateTime '-Epoch-' num2str(maxEpochs) '.mat'],'net','options');
else 
    load(fullfile(imageDir,'trainedUnet','multispectralUnet.mat'));
end

이제 U-Net을 사용하여 다중분광 영상의 의미론적 분할을 수행할 수 있습니다.

테스트 데이터에 대한 결과 예측하기

훈련된 신경망에서 순방향 통과를 수행하려면 헬퍼 함수 segmentImage를 검증 데이터 세트와 함께 사용하십시오. 이 함수는 예제에 지원 파일로 첨부되어 있습니다. segmentImagesemanticseg (Computer Vision Toolbox) 함수를 사용하여 영상 패치에 대한 분할을 수행합니다.

predictPatchSize = [1024 1024];
segmentedImage = segmentImage(val_data,net,predictPatchSize);

분할에서 유효한 부분만 추출하려면 분할된 영상에 검증 데이터의 마스크 채널을 곱하십시오.

segmentedImage = uint8(val_data(:,:,7)~=0) .* segmentedImage;

figure
imshow(segmentedImage,[])
title('Segmented Image')

의미론적 분할의 출력에 잡음이 있습니다. 잡음 및 고립된 픽셀을 제거하려면 영상 후처리를 수행하십시오. 분할에 섞여 있는 점잡음을 제거하려면 medfilt2 함수를 사용하십시오. 잡음을 제거한 분할된 영상을 시각화합니다.

segmentedImage = medfilt2(segmentedImage,[7,7]);
imshow(segmentedImage,[]);
title('Segmented Image  with Noise Removed')

히스토그램을 평활화한 RGB 검증 영상 위에 분할된 영상을 겹쳐 놓습니다.

B = labeloverlay(histeq(val_data(:,:,[3 2 1])),segmentedImage,'Transparency',0.8,'Colormap',cmap);

figure
imshow(B)
title('Labeled Validation Image')
colorbar('TickLabels',cellstr(classNames),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none');
colormap(cmap)

분할된 영상 및 실측 레이블을 PNG 파일로 저장합니다. 이는 정확도 메트릭 계산에 사용합니다.

imwrite(segmentedImage,'results.png');
imwrite(val_labels,'gtruth.png');

분할 정확도 정량화하기

분할 결과 및 실측 레이블을 위한 pixelLabelDatastore (Computer Vision Toolbox)를 생성합니다.

pxdsResults = pixelLabelDatastore('results.png',classNames,pixelLabelIds);
pxdsTruth = pixelLabelDatastore('gtruth.png',classNames,pixelLabelIds);

evaluateSemanticSegmentation (Computer Vision Toolbox) 함수를 사용하여 의미론적 분할의 전역 정확도를 측정합니다.

ssm = evaluateSemanticSegmentation(pxdsResults,pxdsTruth,'Metrics','global-accuracy');
Evaluating semantic segmentation results
----------------------------------------
* Selected metrics: global accuracy.
* Processed 1 images.
* Finalizing... Done.
* Data set metrics:

    GlobalAccuracy
    ______________

       0.90698    

전역 정확도 점수에 따르면, 픽셀의 90% 이상이 올바르게 분류되었습니다.

식생 피복의 규모 계산하기

이 예제에서의 최종 목표는 다중분광 영상에서 식생 피복의 규모를 계산하는 것입니다.

식생으로 레이블이 지정된 픽셀의 수를 확인합니다. 레이블 ID 2("Trees"), 13("LowLevelVegetation") 및 14("Grass_Lawn")는 식생 클래스입니다. 또한 마스크 영상의 ROI에 있는 픽셀을 합하여 총 유효 픽셀 수를 계산합니다.

vegetationClassIds = uint8([2,13,14]);
vegetationPixels = ismember(segmentedImage(:),vegetationClassIds);
validPixels = (segmentedImage~=0);

numVegetationPixels = sum(vegetationPixels(:));
numValidPixels = sum(validPixels(:));

식생 픽셀의 수를 유효 픽셀 수로 나누어 식생 피복의 비율을 계산합니다.

percentVegetationCover = (numVegetationPixels/numValidPixels)*100;
fprintf('The percentage of vegetation cover is %3.2f%%.',percentVegetationCover);
The percentage of vegetation cover is 51.72%.

참고 문헌

[1] Kemker, R., C. Salvaggio, C. Kanan. "High-Resolution Multispectral Dataset for Semantic Segmentation." CoRR, abs/1703.01918. 2017.

[2] Ronneberger, O., P. Fischer, T. Brox. "U-Net: Convolutional Networks for Biomedical Image Segmentation." CoRR, abs/1505.04597. 2015.

참고 항목

| | | (Computer Vision Toolbox) | (Computer Vision Toolbox) | (Computer Vision Toolbox) | (Computer Vision Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox)

관련 항목

외부 웹 사이트