(Matlab) 딥러닝을 사용한 Semantic Segmentation

(Matlab) 딥러닝을 사용한 Semantic Segmentation


1. Data 준비

1.1. image labeling

Image Labelr를 사용한다.

  1. image Import - From File - 원본 images 폴더 열기

2. image

3. image

4. image image Pixel label 선택하고 class name지정, 주의할 점은 클래스가 2개 이상이여야함! background도 라벨링하기

5. image 불러온 원본 이미지 모두 위와 같이 라벨링해주기.

  1. image 라벨링 다 되면
    Export - To file : 바탕화면에 PixelLabelData라는 이름으로 라벨링된 이미지들이 저장되어 있는 폴더가 생성됨.
    Export - To workspace : gTruth.mat 파일 생성됨.

1.2. dataset 준비

# 원본 이미지 폴더 열어서 image Directory로 만들기
imDir = fullfile('C:','Users','유다연','Desktop','images');
imds = imageDatastore(imDir);

# 라벨링된 이미지로 pixel Directory 만들기
classNames = ["lane" "background"];
pixelLabelID = [1 2];
pxDir = fullfile('C:','Users','유다연','Desktop','PixelLabelData');
pxds = pixelLabelDatastore(pxDir,classNames,pixelLabelID);


####### Image dataset #######
# Dataset 설정
rng(0); 
numFiles = numel(imds.Files);
shuffledIndices = randperm(numFiles);

# 전체 데이터의 60%는 훈련 데이터
numTrain = round(0.60 * numFiles);
trainingIdx = shuffledIndices(1:numTrain);
numVal = round(0.20 * numFiles);

# 검증 데이터, 테스트 데이터는 각각 20%
valIdx = shuffledIndices(numTrain+1:numTrain+numVal);
testIdx = shuffledIndices(numTrain+numVal+1:end);

trainingImages = imds.Files(trainingIdx);
valImages = imds.Files(valIdx);
testImages = imds.Files(testIdx);

# imageDatastore에 담아야 훈련에 쓸 수 있다.
imdsTrain = imageDatastore(trainingImages);
imdsVal = imageDatastore(valImages);
imdsTest = imageDatastore(testImages);


####### Label dataset #######
trainingLabels = pxds.Files(trainingIdx);
valLabels = pxds.Files(valIdx);
testLabels = pxds.Files(testIdx);

# label은 pixelLabelDatastore에 담아야 쓸 수 있다. 
pxdsTrain = pixelLabelDatastore(trainingLabels, classNames, pixelLabelID);
pxdsVal = pixelLabelDatastore(valLabels, classNames, pixelLabelID);
pxdsTest = pixelLabelDatastore(testLabels, classNames, pixelLabelID);


# 이미지와 레이블을 묶어서 훈련 및 검증 데이터로 만들어줌.
trainingData = combine(imdsTrain,pxdsTrain);
validationData = combine(imdsVal,pxdsVal);

데이터셋 만들고 잘 됐는지 확인 한번….

I = readimage(imds,1);
I = histeq(I);
imshow(I)


classNames = ["lane" "background"];
pixelLabelID = [1 2];
pxDir = fullfile('C:','Users','유다연','Desktop','PixelLabelData');
pxds = pixelLabelDatastore(pxDir,classNames,pixelLabelID);

C = readimage(pxds,1);
B = labeloverlay(I,C);
figure
imshow(B)


tbl = countEachLabel(pxds)
frequency = tbl.PixelCount/sum(tbl.PixelCount);

bar(1:numel(classNames),frequency)
xticks(1:numel(classNames)) 
xticklabels(tbl.Name)
xtickangle(45)
ylabel('Frequency')

image image 원본이미지 * label을 같이 보여주면서 클래스 빈도수를 나타내줌. 배경의 영역이 더 큰걸 알 수 있다.

2. training

% Specify the network image size. This is typically the same as the traing image sizes.
imageSize = [480 660 3];

% Specify the number of classes.
numClasses = numel(classNames);

% Create DeepLab v3+.
lgraph = deeplabv3plusLayers(imageSize, numClasses, "resnet18");


numFilters = 64;
filterSize = 3;

layers = [
    imageInputLayer([480 660 3])
    convolution2dLayer(filterSize,numFilters,'Padding',1)
    reluLayer()
    maxPooling2dLayer(2,'Stride',2)
    convolution2dLayer(filterSize,numFilters,'Padding',1)
    reluLayer()
    transposedConv2dLayer(4,numFilters,'Stride',2,'Cropping',1);
    convolution2dLayer(1,numClasses);
    softmaxLayer()
    pixelClassificationLayer()
    ];
opts = trainingOptions('sgdm', ...
    'InitialLearnRate',1e-3, ...
    'MaxEpochs',10, ...
    'MiniBatchSize',10);

trainingData = combine(imdsTrain,pxdsTrain);
net = trainNetwork(trainingData,layers,opts);

아주 간단하게 네트워크를 구성했음.
image

3. Test

I = readimage(imdsTest,19);
C = semanticseg(I, net);

B = labeloverlay(I,C,'Transparency',0.4);
figure
imshow(B)

test 데이터에서 임의의 사진에 대해 test image 결과 개노답처럼 보이지만 데이터가 부족한 점 + 아주 간단한 신경망이라는 점 등을 고려하면 ㄱㅊ….다음엔 성능을 높여보자!

참고자료

딥러닝을 사용한 의미론적 분할 pixelLabelDatastore How Labeler Apps Store Exported Pixel Labels