(Matlab) 딥러닝을 사용한 Semantic Segmentation
on Projects
1. Data 준비
1.1. image labeling
Image Labelr를 사용한다.
- Import - From File - 원본 images 폴더 열기
2.
3.
4. Pixel label 선택하고 class name지정, 주의할 점은 클래스가 2개 이상이여야함! background도 라벨링하기
5. 불러온 원본 이미지 모두 위와 같이 라벨링해주기.
- 라벨링 다 되면
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')
원본이미지 * 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);
아주 간단하게 네트워크를 구성했음.
3. Test
I = readimage(imdsTest,19);
C = semanticseg(I, net);
B = labeloverlay(I,C,'Transparency',0.4);
figure
imshow(B)
test 데이터에서 임의의 사진에 대해 test 결과 개노답처럼 보이지만 데이터가 부족한 점 + 아주 간단한 신경망이라는 점 등을 고려하면 ㄱㅊ….다음엔 성능을 높여보자!
참고자료
딥러닝을 사용한 의미론적 분할 pixelLabelDatastore How Labeler Apps Store Exported Pixel Labels