このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
深層学習を使用したセマンティック セグメンテーション
セマンティック セグメンテーション用の学習データの解析
セマンティック セグメンテーション ネットワークに学習させるには、イメージ コレクションと対応するピクセル ラベル付きイメージ コレクションが必要です。ピクセル ラベル付きイメージは、すべてのピクセル値がそのピクセルのカテゴリカル ラベルを表すイメージです。
次のコードでは、イメージの小さなセットとそれに対応するピクセル ラベル付きイメージが読み込まれます。
dataDir = fullfile(toolboxdir('vision'),'visiondata'); imDir = fullfile(dataDir,'building'); pxDir = fullfile(dataDir,'buildingPixelLabels');
imageDatastore
を使用してイメージ データを読み込みます。イメージは必要な場合にのみメモリに読み取られるため、イメージ データストアは大規模なイメージ コレクションを効率的に表すことができます。
imds = imageDatastore(imDir);
最初のイメージを読み取って表示します。
I = readimage(imds,1); figure imshow(I)
pixelLabelDatastore
を使用してピクセル ラベル イメージを読み込み、ラベル ID とカテゴリカル名の間のマッピングを定義します。ここで使用されているデータセットでは、ラベルは "sky"、"grass"、"building"、および "sidewalk" です。これらのクラスのラベル ID はそれぞれ 1、2、3、4 です。
クラス名を定義します。
classNames = ["sky" "grass" "building" "sidewalk"];
各クラス名のラベル ID を定義します。
pixelLabelID = [1 2 3 4];
pixelLabelDatastore
を作成します。
pxds = pixelLabelDatastore(pxDir,classNames,pixelLabelID);
最初のピクセル ラベル イメージを読み取ります。
C = readimage(pxds,1);
出力 C
は categorical 行列です。ここで、C(i,j)
はピクセル I(i,j)
のカテゴリカル ラベルです。
C(5,5)
ans = categorical
sky
イメージにピクセル ラベルを重ね合わせて、イメージのさまざまな部分へのラベル付けを確認します。
B = labeloverlay(I,C); figure imshow(B)
カテゴリカル出力形式を使うと、クラス名別での操作が必要なタスクが簡略化されます。たとえば、次のように建物だけのバイナリ マスクを作成できます。
buildingMask = C == 'building'; figure imshowpair(I, buildingMask,'montage')
セマンティック セグメンテーション ネットワークの作成
簡単なセマンティック セグメンテーション ネットワークを作成し、多くのセマンティック セグメンテーション ネットワークで検出された共通の層について学習します。セマンティック セグメンテーション ネットワークの共通パターンでは、畳み込み層と ReLU 層間でイメージをダウンサンプリングした後、入力サイズを一致させるために出力をアップサンプリングする必要があります。この操作は、イメージ ピラミッドを使用した標準のスケールスペース解析に類似しています。ただし、このプロセス中、ネットワークはセグメント化するクラスの特定のセットに対して最適化されている非線形フィルターを使用して操作を実行します。
イメージ入力層の作成
セマンティック セグメンテーション ネットワークは imageInputLayer
から始まります。これは、ネットワークで処理できる最小のイメージ サイズを定義します。ほとんどのセマンティック セグメンテーション ネットワークは完全畳み込みです。つまり、指定の入力サイズよりも大きいイメージを処理できます。ここでは、64x64 の RGB イメージを処理するネットワークで [32 32 3] のイメージ サイズが使用されています。
inputSize = [32 32 3]; imgLayer = imageInputLayer(inputSize)
imgLayer = ImageInputLayer with properties: Name: '' InputSize: [32 32 3] Hyperparameters DataAugmentation: 'none' Normalization: 'zerocenter'
ダウンサンプリング ネットワークの作成
畳み込み層と ReLU 層から始めます。畳み込み層の出力サイズが入力サイズと同じになるように、畳み込み層のパディングが選択されています。これによって、ネットワークで処理を進める間、ほとんどの層間の入力サイズと出力サイズが変わらないため、ネットワークが作成しやすくなります。
filterSize = 3;
numFilters = 32;
conv = convolution2dLayer(filterSize,numFilters,'Padding',1);
relu = reluLayer();
ダウンサンプリングは、最大プーリング層を使用して実行されます。'Stride
' パラメーターを 2 に設定することで、入力を 2 の係数でダウンサンプリングする最大プーリング層を作成します。
poolSize = 2;
maxPoolDownsample2x = maxPooling2dLayer(poolSize,'Stride',2);
畳み込み層、ReLU 層および最大プール層を積み重ねて、その入力を 4 の係数でダウンサンプリングするネットワークを作成します。
downsamplingLayers = [ conv relu maxPoolDownsample2x conv relu maxPoolDownsample2x ]
downsamplingLayers = 6x1 Layer array with layers: 1 '' Convolution 32 3x3 convolutions with stride [1 1] and padding [1 1 1 1] 2 '' ReLU ReLU 3 '' Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 4 '' Convolution 32 3x3 convolutions with stride [1 1] and padding [1 1 1 1] 5 '' ReLU ReLU 6 '' Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0]
アップサンプリング ネットワークの作成
アップサンプリングは、転置畳み込み層 (一般的には "deconv" または "逆畳み込み" 層とも呼びます) を使用して実行されます。転置畳み込みがアップサンプリングに使用されている場合、アップサンプリングとフィルター処理が同時に実行されます。
2 でアップサンプリングする転置畳み込み層を作成します。
filterSize = 4; transposedConvUpsample2x = transposedConv2dLayer(4,numFilters,'Stride',2,'Cropping',1);
出力サイズが入力サイズの 2 倍になるよう 'Cropping' パラメーターが 1 に設定されています。
転置畳み込み層と ReLU 層を積み重ねます。この層のセットへの入力は 4 でアップサンプリングされます。
upsamplingLayers = [ transposedConvUpsample2x relu transposedConvUpsample2x relu ]
upsamplingLayers = 4x1 Layer array with layers: 1 '' Transposed Convolution 32 4x4 transposed convolutions with stride [2 2] and output cropping [1 1] 2 '' ReLU ReLU 3 '' Transposed Convolution 32 4x4 transposed convolutions with stride [2 2] and output cropping [1 1] 4 '' ReLU ReLU
ピクセル分類層の作成
最終的な層のセットは、ピクセル分類の作成を行います。これらの最終層は、入力イメージと同じ空間次元 (高さと幅) を持つ入力を処理します。ただし、チャネル数 (3 番目の次元) は大きく、最後の転置畳み込み層フィルター数と同じになります。この 3 つ目の次元を、セグメント化するクラス数まで絞り込む必要があります。これを実行するには、フィルターの数がクラス数 (3 など) と一致する 1 行 1 列の畳み込み層を使用します。
入力特徴マップの 3 番目の次元をクラス数まで結合する畳み込み層を作成します。
numClasses = 3; conv1x1 = convolution2dLayer(1,numClasses);
この 1 行 1 列の畳み込み層の後に、ソフトマックス層とピクセル分類層が続きます。これらの 2 つの層が結合されて、各イメージ ピクセルのカテゴリカル ラベルが予測されます。
finalLayers = [ conv1x1 softmaxLayer() pixelClassificationLayer() ]
finalLayers = 3x1 Layer array with layers: 1 '' Convolution 3 1x1 convolutions with stride [1 1] and padding [0 0 0 0] 2 '' Softmax softmax 3 '' Pixel Classification Layer Cross-entropy loss
すべての層の積み重ね
すべての層を積み重ねて、セマンティック セグメンテーション ネットワークを完成させます。
net = [ imgLayer downsamplingLayers upsamplingLayers finalLayers ]
net = 14x1 Layer array with layers: 1 '' Image Input 32x32x3 images with 'zerocenter' normalization 2 '' Convolution 32 3x3 convolutions with stride [1 1] and padding [1 1 1 1] 3 '' ReLU ReLU 4 '' Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 5 '' Convolution 32 3x3 convolutions with stride [1 1] and padding [1 1 1 1] 6 '' ReLU ReLU 7 '' Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 8 '' Transposed Convolution 32 4x4 transposed convolutions with stride [2 2] and output cropping [1 1] 9 '' ReLU ReLU 10 '' Transposed Convolution 32 4x4 transposed convolutions with stride [2 2] and output cropping [1 1] 11 '' ReLU ReLU 12 '' Convolution 3 1x1 convolutions with stride [1 1] and padding [0 0 0 0] 13 '' Softmax softmax 14 '' Pixel Classification Layer Cross-entropy loss
このネットワークには、Deep Learning Toolbox™ の trainNetwork
を使用して学習させることができます。
セマンティック セグメンテーション ネットワークの学習
学習データを読み込みます。
dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages'); imageDir = fullfile(dataSetDir,'trainingImages'); labelDir = fullfile(dataSetDir,'trainingLabels');
イメージのイメージ データストアを作成します。
imds = imageDatastore(imageDir);
グラウンド トゥルース ピクセル ラベル用の pixelLabelDatastore
を作成します。
classNames = ["triangle","background"]; labelIDs = [255 0]; pxds = pixelLabelDatastore(labelDir,classNames,labelIDs);
学習イメージとグラウンド トゥルース ピクセル ラベルを可視化します。
I = read(imds);
C = read(pxds);
I = imresize(I,5);
L = imresize(uint8(C{1}),5);
imshowpair(I,L,'montage')
セマンティック セグメンテーション ネットワークを作成します。このネットワークでは、ダウンサンプリングおよびアップサンプリングの設計に基づいてシンプルなセマンティック セグメンテーション ネットワークを使用します。
numFilters = 64; filterSize = 3; numClasses = 2; layers = [ imageInputLayer([32 32 1]) 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',100, ... 'MiniBatchSize',64);
イメージ データストアとピクセル ラベル データストアを学習用に統合します。
trainingData = combine(imds,pxds);
ネットワークに学習をさせます。
net = trainNetwork(trainingData,layers,opts);
Training on single CPU. Initializing input data normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:00 | 58.11% | 1.3458 | 0.0010 | | 17 | 50 | 00:00:12 | 97.30% | 0.0924 | 0.0010 | | 34 | 100 | 00:00:24 | 98.09% | 0.0575 | 0.0010 | | 50 | 150 | 00:00:37 | 98.56% | 0.0424 | 0.0010 | | 67 | 200 | 00:00:49 | 98.48% | 0.0435 | 0.0010 | | 84 | 250 | 00:01:02 | 98.66% | 0.0363 | 0.0010 | | 100 | 300 | 00:01:14 | 98.90% | 0.0310 | 0.0010 | |========================================================================================| Training finished: Reached final iteration.
テスト イメージを読み取って表示します。
testImage = imread('triangleTest.jpg');
imshow(testImage)
テスト イメージをセグメント化し、結果を表示します。
C = semanticseg(testImage,net); B = labeloverlay(testImage,C); imshow(B)
セマンティック セグメンテーションの結果の評価と検査
テスト データ セットをインポートして、事前学習済みのセマンティック セグメンテーション ネットワークを実行し、予測される結果に対してセマンティック セグメンテーションの品質メトリクスを検査します。
データセットのインポート
triangleImages
データセットには、グラウンド トゥルース ラベルの付いた 100 個のテスト イメージがあります。データセットの場所を定義します。
dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages');
テスト イメージの場所を定義します。
testImagesDir = fullfile(dataSetDir,'testImages');
テスト イメージを保持する imageDatastore
オブジェクトを作成します。
imds = imageDatastore(testImagesDir);
グラウンド トゥルース ラベルの場所を定義します。
testLabelsDir = fullfile(dataSetDir,'testLabels');
クラス名と関連するラベル ID を定義します。ラベル ID は、イメージ ファイルで各クラスを表すために使用されるピクセル値です。
classNames = ["triangle" "background"]; labelIDs = [255 0];
テスト イメージのグラウンド トゥルース ピクセル ラベルを保持する pixelLabelDatastore
オブジェクトを作成します。
pxdsTruth = pixelLabelDatastore(testLabelsDir,classNames,labelIDs);
セマンティック セグメンテーション分類器の実行
triangleImages
の学習イメージで学習させられたセマンティック セグメンテーション ネットワークを読み込みます。
net = load('triangleSegmentationNetwork.mat');
net = net.net;
テスト イメージでネットワークを実行します。予測されたラベルは、一時ディレクトリのディスクに書き込まれ、pixelLabelDatastore
オブジェクトとして返されます。
pxdsResults = semanticseg(imds,net,"WriteLocation",tempdir);
Running semantic segmentation network ------------------------------------- * Processed 100 images.
予測の品質の評価
予測されたラベルはグラウンド トゥルース ラベルと比較されます。セマンティック セグメンテーション メトリクスが計算されている間、進行状況がコマンド ウィンドウに出力されます。
metrics = evaluateSemanticSegmentation(pxdsResults,pxdsTruth);
Evaluating semantic segmentation results ---------------------------------------- * Selected metrics: global accuracy, class accuracy, IoU, weighted IoU, BF score. * Processed 100 images. * Finalizing... Done. * Data set metrics: GlobalAccuracy MeanAccuracy MeanIoU WeightedIoU MeanBFScore ______________ ____________ _______ ___________ ___________ 0.90624 0.95085 0.61588 0.87529 0.40652
クラス メトリクスの検査
データセットの各クラスの分類の精度、Intersection over Union (IoU)、および境界 F-1 スコアを表示します。
metrics.ClassMetrics
ans=2×3 table
Accuracy IoU MeanBFScore
________ _______ ___________
triangle 1 0.33005 0.028664
background 0.9017 0.9017 0.78438
混同行列の表示
混同行列を表示します。
metrics.ConfusionMatrix
ans=2×2 table
triangle background
________ __________
triangle 4730 0
background 9601 88069
正規化された混同行列を Figure ウィンドウのヒート マップとして可視化します。
normConfMatData = metrics.NormalizedConfusionMatrix.Variables; figure h = heatmap(classNames,classNames,100*normConfMatData); h.XLabel = 'Predicted Class'; h.YLabel = 'True Class'; h.Title = 'Normalized Confusion Matrix (%)';
イメージ メトリクスの検査
イメージごとの Intersection over Union (IoU) のヒストグラムを可視化します。
imageIoU = metrics.ImageMetrics.MeanIoU;
figure
histogram(imageIoU)
title('Image Mean IoU')
最小の IoU を持つテスト イメージを見つけます。
[minIoU, worstImageIndex] = min(imageIoU); minIoU = minIoU(1); worstImageIndex = worstImageIndex(1);
比較用に、最悪の IoU を持つテスト イメージ、そのグラウンド トゥルース ラベル、およびその予測されたラベルを読み取ります。
worstTestImage = readimage(imds,worstImageIndex); worstTrueLabels = readimage(pxdsTruth,worstImageIndex); worstPredictedLabels = readimage(pxdsResults,worstImageIndex);
ラベル イメージを Figure ウィンドウに表示できるイメージに変換します。
worstTrueLabelImage = im2uint8(worstTrueLabels == classNames(1)); worstPredictedLabelImage = im2uint8(worstPredictedLabels == classNames(1));
最悪のテスト イメージ、グラウンド トゥルースおよび予測を表示します。
worstMontage = cat(4,worstTestImage,worstTrueLabelImage,worstPredictedLabelImage); worstMontage = imresize(worstMontage,4,"nearest"); figure montage(worstMontage,'Size',[1 3]) title(['Test Image vs. Truth vs. Prediction. IoU = ' num2str(minIoU)])
同様に、最高の IoU を持つテスト イメージを見つけます。
[maxIoU, bestImageIndex] = max(imageIoU); maxIoU = maxIoU(1); bestImageIndex = bestImageIndex(1);
前の手順を繰り返して、最高の IoU を持つテスト イメージをそのグラウンド トゥルースおよび予測されたラベルと共に読み取り、変換し、表示します。
bestTestImage = readimage(imds,bestImageIndex); bestTrueLabels = readimage(pxdsTruth,bestImageIndex); bestPredictedLabels = readimage(pxdsResults,bestImageIndex); bestTrueLabelImage = im2uint8(bestTrueLabels == classNames(1)); bestPredictedLabelImage = im2uint8(bestPredictedLabels == classNames(1)); bestMontage = cat(4,bestTestImage,bestTrueLabelImage,bestPredictedLabelImage); bestMontage = imresize(bestMontage,4,"nearest"); figure montage(bestMontage,'Size',[1 3]) title(['Test Image vs. Truth vs. Prediction. IoU = ' num2str(maxIoU)])
評価するメトリクスの指定
オプションで、'Metrics'
パラメーターを使用して評価するメトリクスをリストします。
計算するメトリクスを定義します。
evaluationMetrics = ["accuracy" "iou"];
triangleImages
テスト データセットについてこれらのメトリクスを計算します。
metrics = evaluateSemanticSegmentation(pxdsResults,pxdsTruth,"Metrics",evaluationMetrics);
Evaluating semantic segmentation results ---------------------------------------- * Selected metrics: class accuracy, IoU. * Processed 100 images. * Finalizing... Done. * Data set metrics: MeanAccuracy MeanIoU ____________ _______ 0.95085 0.61588
クラスごとに選択したメトリクスを表示します。
metrics.ClassMetrics
ans=2×2 table
Accuracy IoU
________ _______
triangle 1 0.33005
background 0.9017 0.9017
セマンティック セグメンテーションのピクセル ラベル付きデータセットのインポート
この例では、セマンティック セグメンテーション ネットワークのピクセル ラベル付きデータセットをインポートする方法を示します。
ピクセル ラベル付きデータセットは、セマンティック セグメンテーション ネットワークに学習させるために使用されるイメージ コレクションと対応するグラウンド トゥルース ピクセル ラベルのセットです。ピクセルごとのラベルで注釈が付けられたイメージを提供する多くのパブリック データセットがあります。これらのタイプのデータセットをインポートする手順を示すために、この例では、ケンブリッジ大学の CamVid データセット [1] を使用します。
CamVid データセットは、運転中に得られた路上レベルでのビューが含まれるイメージ コレクションです。データセットは、車、歩行者、道路を含む 32 個のセマンティック クラスについてピクセルレベルのラベルを提供します。CamVid をインポートするための手順を使用して、他のピクセル ラベル付きデータセットをインポートできます。
CamVid データセットのダウンロード
次の URL から CamVid イメージ データをダウンロードします。
imageURL = 'http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/files/701_StillsRaw_full.zip'; labelURL = 'http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/LabeledApproved_full.zip'; outputFolder = fullfile(tempdir, 'CamVid'); imageDir = fullfile(outputFolder,'images'); labelDir = fullfile(outputFolder,'labels'); if ~exist(outputFolder, 'dir') disp('Downloading 557 MB CamVid data set...'); unzip(imageURL, imageDir); unzip(labelURL, labelDir); end
メモ: データのダウンロードにかかる時間はインターネット接続の速度によって異なります。上記で使用したコマンドは、ダウンロードが完了するまで MATLAB® をブロックします。別の方法として、Web ブラウザーを使用して、データセットをローカル ディスクにまずダウンロードしておくことができます。Web からダウンロードしたファイルを使用するには、上記の変数 outputFolder
の値を、ダウンロードしたファイルの場所に変更します。
CamVid ピクセル ラベル
CamVid データセットはピクセル ラベルを RGB イメージとして符号化します。RGB イメージでは各クラスが RGB カラーで表されます。以下に、データセットで RGB 符号化と共に定義するクラスを示します。
classNames = [ ... "Animal", ... "Archway", ... "Bicyclist", ... "Bridge", ... "Building", ... "Car", ... "CartLuggagePram", ... "Child", ... "Column_Pole", ... "Fence", ... "LaneMkgsDriv", ... "LaneMkgsNonDriv", ... "Misc_Text", ... "MotorcycleScooter", ... "OtherMoving", ... "ParkingBlock", ... "Pedestrian", ... "Road", ... "RoadShoulder", ... "Sidewalk", ... "SignSymbol", ... "Sky", ... "SUVPickupTruck", ... "TrafficCone", ... "TrafficLight", ... "Train", ... "Tree", ... "Truck_Bus", ... "Tunnel", ... "VegetationMisc", ... "Wall"];
classNames(k)
が labelIDs(k,:)
に対応するようにラベル インデックスとクラス名間のマッピングを定義します。
labelIDs = [ ... 064 128 064; ... % "Animal" 192 000 128; ... % "Archway" 000 128 192; ... % "Bicyclist" 000 128 064; ... % "Bridge" 128 000 000; ... % "Building" 064 000 128; ... % "Car" 064 000 192; ... % "CartLuggagePram" 192 128 064; ... % "Child" 192 192 128; ... % "Column_Pole" 064 064 128; ... % "Fence" 128 000 192; ... % "LaneMkgsDriv" 192 000 064; ... % "LaneMkgsNonDriv" 128 128 064; ... % "Misc_Text" 192 000 192; ... % "MotorcycleScooter" 128 064 064; ... % "OtherMoving" 064 192 128; ... % "ParkingBlock" 064 064 000; ... % "Pedestrian" 128 064 128; ... % "Road" 128 128 192; ... % "RoadShoulder" 000 000 192; ... % "Sidewalk" 192 128 128; ... % "SignSymbol" 128 128 128; ... % "Sky" 064 128 192; ... % "SUVPickupTruck" 000 000 064; ... % "TrafficCone" 000 064 064; ... % "TrafficLight" 192 064 128; ... % "Train" 128 128 000; ... % "Tree" 192 128 192; ... % "Truck_Bus" 064 000 064; ... % "Tunnel" 192 192 000; ... % "VegetationMisc" 064 192 000]; % "Wall"
他のデータセットは符号化データの形式が異なることに注意してください。たとえば、PASCAL VOC [2] データセットでは、0 ~ 21 の数値ラベル ID を使用してそれらのクラス ラベルを符号化します。
CamVid イメージのいずれか 1 つに対してピクセル ラベルを可視化します。
labels = imread(fullfile(labelDir,'0001TP_006690_L.png')); figure imshow(labels) % Add colorbar to show class to color mapping. N = numel(classNames); ticks = 1/(N*2):1/N:1; colorbar('TickLabels',cellstr(classNames),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none'); colormap(labelIDs./255)
CamVid データの読み込み
ピクセル ラベル付きデータセットは、imageDatastore
および pixelLabelDatastore
を使用して読み込むことができます。
CamVid イメージを読み込む imageDatastore
を作成します。
imds = imageDatastore(fullfile(imageDir,'701_StillsRaw_full'));
CamVid ピクセル ラベルを読み込む pixelLabelDatastore
を作成します。
pxds = pixelLabelDatastore(labelDir,classNames,labelIDs);
10 番目のイメージと対応するピクセル ラベル イメージを読み取ります。
I = readimage(imds,10); C = readimage(pxds,10);
ピクセル ラベル イメージは categorical 配列として返されます。この配列では、C(i,j)
がピクセル I(i,j)
に割り当てられたカテゴリカル ラベルになります。イメージの上にピクセル ラベル イメージを表示します。
B = labeloverlay(I,C,'Colormap',labelIDs./255); figure imshow(B) % Add a colorbar. N = numel(classNames); ticks = 1/(N*2):1/N:1; colorbar('TickLabels',cellstr(classNames),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none'); colormap(labelIDs./255)
undefined ラベルまたは void ラベル
ピクセル ラベル付きデータセットには "undefined" ラベルまたは "void" ラベルを含めるのが一般的です。これらは、ラベル付けされていないピクセルを示すために使用されます。たとえば、CamVid では、ラベル ID [0 0 0] は "void" クラスを指定するために使用されます。学習アルゴリズムと評価アルゴリズムでは、どの計算にもこれらのラベルが含まれないものと見なされます。
"void" クラスは、pixelLabelDatastore
を使用するときに明示的に名前を付ける必要はありません。クラス名にマッピングされていないラベル ID には自動的に "undefined" のラベルが付き、計算対象から除外されます。未定義のピクセルを確認するには、isundefined
を使用してマスクを作成した後、そのマスクをイメージの上に表示します。
undefinedPixels = isundefined(C);
B = labeloverlay(I,undefinedPixels);
figure
imshow(B)
title('Undefined Pixel Labels')
クラスの結合
パブリック データセットを使用する場合は、アプリケーションにより適合するよういくつかのクラスを結合しなければならない場合があります。たとえば、シーンを道路、空、自動車、歩行者の 4 つのクラスと背景にセグメント化するセマンティック セグメンテーション ネットワークに学習させる場合を考えます。これを CamVid データセットで行うには、上記で定義したラベル ID を新しいクラスに合わせてグループ化します。最初に、新しいクラス名を定義します。
newClassNames = ["road","sky","vehicle","pedestrian","background"];
次に、M 行 3 列の行列のセル配列を使用してラベル ID をグループ化します。
groupedLabelIDs = { % road [ 128 064 128; ... % "Road" 128 000 192; ... % "LaneMkgsDriv" 192 000 064; ... % "LaneMkgsNonDriv" 000 000 192; ... % "Sidewalk" 064 192 128; ... % "ParkingBlock" 128 128 192; ... % "RoadShoulder" ] % "sky" [ 128 128 128; ... % "Sky" ] % "vehicle" [ 064 000 128; ... % "Car" 064 128 192; ... % "SUVPickupTruck" 192 128 192; ... % "Truck_Bus" 192 064 128; ... % "Train" 000 128 192; ... % "Bicyclist" 192 000 192; ... % "MotorcycleScooter" 128 064 064; ... % "OtherMoving" ] % "pedestrian" [ 064 064 000; ... % "Pedestrian" 192 128 064; ... % "Child" 064 000 192; ... % "CartLuggagePram" 064 128 064; ... % "Animal" ] % "background" [ 128 128 000; ... % "Tree" 192 192 000; ... % "VegetationMisc" 192 128 128; ... % "SignSymbol" 128 128 064; ... % "Misc_Text" 000 064 064; ... % "TrafficLight" 064 064 128; ... % "Fence" 192 192 128; ... % "Column_Pole" 000 000 064; ... % "TrafficCone" 000 128 064; ... % "Bridge" 128 000 000; ... % "Building" 064 192 000; ... % "Wall" 064 000 064; ... % "Tunnel" 192 000 128; ... % "Archway" ] };
新しいクラスとラベル ID を使用して pixelLabelDatastore
を作成します。
pxds = pixelLabelDatastore(labelDir,newClassNames,groupedLabelIDs);
10 番目のピクセル ラベル イメージを読み取り、イメージの上に表示します。
C = readimage(pxds,10); cmap = jet(numel(newClassNames)); B = labeloverlay(I,C,'Colormap',cmap); figure imshow(B) % add colorbar N = numel(newClassNames); ticks = 1/(N*2):1/N:1; colorbar('TickLabels',cellstr(newClassNames),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none'); colormap(cmap)
新しいクラス名を持つ pixelLabelDatastore
を使用すると、元の CamVid ピクセル ラベルを変更せずに、4 クラスについてネットワークに学習させることができます。
参考文献
[1] Brostow, Gabriel J., Julien Fauqueur, and Roberto Cipolla."Semantic object classes in video: A high-definition ground truth database." Pattern Recognition Letters 30.2 (2009): 88-97.
[2] Everingham, M., et al. "The PASCAL visual object classes challenge 2012 results." http://www. pascal-network. org/challenges/VOC/voc2012/workshop/index. html Vol. 5. 2012.