본문 바로가기

MATLAB/ㄴ 영상 딥러닝

예제_Faster R-CNN 딥러닝을 사용한 객체 검출

0.참고 자료

 

https://kr.mathworks.com/help/deeplearning/ug/object-detection-using-faster-r-cnn-deep-learning.html#DeepLearningFasterRCNNObjectDetectionExample-1

 

Faster R-CNN 딥러닝을 사용한 객체 검출 - MATLAB & Simulink - MathWorks 한국

이 예제의 수정된 버전이 있습니다. 사용자가 편집한 내용을 반영하여 이 예제를 여시겠습니까?

kr.mathworks.com

 

 

1. 사전훈련된 검출기 다운로드

 


doTraining = false;
if ~doTraining && ~exist('fasterRCNNResNet50EndToEndVehicleExample.mat','file')
    disp('Downloading pretrained detector (118 MB)...');
    pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/fasterRCNNResNet50EndToEndVehicleExample.mat';
    websave('fasterRCNNResNet50EndToEndVehicleExample.mat',pretrainedURL);
end

 

 

2. 데이터셋 불러오기

 


unzip vehicleDatasetImages.zip
data = load('vehicleDatasetGroundTruth.mat');
vehicleDataset = data.vehicleDataset;

 

 

3. 데이터셋을 훈련, 검증, 테스트 데이터셋으로 분할.

 


rng(0)
shuffledIndices = randperm(height(vehicleDataset));
idx = floor(0.6 * height(vehicleDataset));

trainingIdx = 1:idx;
trainingDataTbl = vehicleDataset(shuffledIndices(trainingIdx),:);

validationIdx = idx+1 : idx + 1 + floor(0.1 * length(shuffledIndices) );
validationDataTbl = vehicleDataset(shuffledIndices(validationIdx),:);

testIdx = validationIdx(end)+1 : length(shuffledIndices);
testDataTbl = vehicleDataset(shuffledIndices(testIdx),:);

 

 

4. imageDatastore과 boxLabelDatastore를 사용하여 데이터저장소를 만듦

 


imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'});
bldsTrain = boxLabelDatastore(trainingDataTbl(:,'vehicle'));

imdsValidation = imageDatastore(validationDataTbl{:,'imageFilename'});
bldsValidation = boxLabelDatastore(validationDataTbl(:,'vehicle'));

imdsTest = imageDatastore(testDataTbl{:,'imageFilename'});
bldsTest = boxLabelDatastore(testDataTbl(:,'vehicle'));

 

 

5. 영상 데이터저장소와 상자 레이블 데이터저장소를 결합

 


trainingData = combine(imdsTrain, bldsTrain);
validationData = combine(imdsValidation, bldsValidation);
testData = combine(imdsTest, bldsTest);

 

 

6. 상자 레이블과 함께 훈련된 영상 중 하나를 표시

 


data = read(trainingData);
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I, 'rectangle', bbox);
annotatedImage = imresize(annotatedImage, 3);
figure
imshow(annotatedImage)

 

 

Faster R-CNN 검출 신경망 만들기

 
신경망 크기 지정
 

inputSize = [224 224 3];

 

훈련데이터의 사물크기를 기반으로 앵커상자를 추정

 

preprocessedTrainingData = transform(trainingData, @(data)preprocessData(data,inputSize));
numAnchors = 3;
anchorBoxes = estimateAnchorBoxes(preprocessedTrainingData,numAnchors)

 

 

 

 

resnet50 모델을 불러옴
 

featureExtractionNetwork = resnet50;

 
 

activation_40_relu를 특징추출계층으로 선택

 

featureLayer = 'activation_40_relu';

 

검출할 클래스의 개수를 정의

 

numClasses = width(vehicleDataset)-1;

 
 

Faster R-CNN 객체 검출 신경망을 만듦

 

lgraph = fasterRCNNLayers(inputSize, numClasses, anchorBoxes, featureExtractionNetwork, featureLayer)

 
 

 

 

데이터 증대
 

augmentedTrainingData = transform(trainingData, @augmentData);

augmentedData = cell(4,1);
for k = 1:4
    data = read(augmentedTrainingData);
    augmentedData{k} = insertShape(data{1},"rectangle", data{2});
    reset(augmentedTrainingData);
end
figure
montage(augmentedData, 'BorderSize', 10)

 
 

 

훈련 데이터 전처리
 

trainingData = transform(augmentedTrainingData, @(data)preprocessData(data,inputSize));
validationData = transform(validationData, @(data)preprocesseData(data,inputSize));

 

전처리된 데이터 읽어들이기
 
 

data = read(trainingData);

 

영상과 경계상자 표시
 

I = data{1};
bbox = data{2};
annotatedImage = insertShape(I, 'rectangle', bbox);
annotatedImage = imresize(annotatedImage, 2);
figure
imshow(annotatedImage)

 

 

Faster R-CNN 훈련시키기

 
신경망 훈련 옵션의 지정

 


options = trainingOptions('sgdm',...
    'MaxEpochs',10,...
    'MiniBatchSize',2,...
    'InitialLearnRate',1e-3,...
    'CheckpointPath',tempdir,...
    'ValidationData',validationData);

 

doTraining이 true인 경우, Faster R-CNN을 훈련시키며, 아닐경우 사전훈련된 신경망을 불러옴
 
 

if doTraining
    [detector, info] = trainFasterRCNNObjectDetector(trainingData, lgraph, options, ...
        'NegativeOverlapRange', [0 0.3], ...
        'PositiveOverlapRange', [0.6 1]);
else
    pretrained = load('fasterRCNNResNet50EndToEndVehicleExample.mat');
    detector = pretrained.detector;
end

 

1개의 테스트 영상에 대해 검출기 실행
 
 

I = imread(testDataTbl.imageFilename{3});
I = imresize(I,inputSize(1:2));
[bboxes, scores] = detect(detector, I);

 

결과 표시
 
 

I = insertObjectAnnotation(I, 'rectangle', bboxes, scores);
figure
imshow(I)

 

 

 

테스트 세트를 사용하여 검출기 평가하기

 
훈련데이터와 동일한 전처리 변환을 테스트 데이터에 적용
 
 

testData = transform(testData, @(data)preprocessData(data,inputSize));

 

모든 테스트 영상에 대해 검출기 실행
 

detectionResults = detect(detector, testData, 'MinibatchSize', 4);

 

평균 정밀도를 사용하여 객체 검출기를 평가
 
 

[ap, recall, precision] = evaluateDetectionPrecision(detectionResults, testData);

 

PR 곡선을 플로팅
 

figure
plot(recall, precision)
xlabel('Recall')
ylabel('Precision')
grid on
title(sprintf('Average Precision = %.2f', ap))

 

 

 

지원 함수
 
 


function data = augmentData(data)
% Randomly flip images and bounding boxes horizontally.
tform = randomAffine2d('XReflection',true);
sz = size(data{1});
rout = affineOutputView(sz,tform);
data{1} = imwarp(data{1},tform,'OutputView',rout);

% Sanitize boxes, if needed. This helper function is attached as a
% supporting file. Open the example in MATLAB to open this function.
% data{2} = helperSanitizeBoxes(data{2});

% Warp boxes.
data{2} = bboxwarp(data{2},tform,rout);
end





function data = preprocessData(data,targetSize)
% Resize image and bounding boxes to targetSize.
sz = size(data{1},[1 2]);
scale = targetSize(1:2)./sz;
data{1} = imresize(data{1},targetSize(1:2));

% Sanitize boxes, if needed. This helper function is attached as a
% supporting file. Open the example in MATLAB to open this function.
% data{2} = helperSanitizeBoxes(data{2});

% Resize boxes.
data{2} = bboxresize(data{2},scale);
end