Main Content

ブロックベースのワークフローにおけるセグメンテーション メトリクスの計算

この例では、blockedImage オブジェクト内の個々のブロックに対してセマンティック セグメンテーション混同行列を計算し、グローバルとブロックのセグメンテーション メトリクスを計算する方法を説明します。

背景に対して三角形のバイナリ セグメンテーションを実行する事前学習済みのネットワークを読み込みます。

load('triangleSegmentationNetwork');

triangleImages データセットには、グラウンド トゥルース ラベルの付いた 100 個のテスト イメージがあります。データセットの場所を定義します。

dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages');

テスト イメージの場所を定義します。

testImagesDir = fullfile(dataSetDir,'testImages');

3 つのテスト イメージを読み取ります。各イメージを 4 の係数でサイズ変更し、データ型を double に変換してから、blockedImage オブジェクトを作成します。blockedImage は、ブロックベースのイメージ処理ワークフローをサポートします。

numImages = 3;
for idx = 1:numImages
    im = imread(fullfile(testImagesDir,['image_' '00' num2str(idx) '.jpg']));
    im = imresize(im,4);
    testImages(idx) = blockedImage(im);
end

最初のテスト イメージを表示します。

bigimageshow(testImages(1))

グラウンド トゥルース ラベルの場所を定義します。

testLabelsDir = fullfile(dataSetDir,'testLabels');

クラス名と関連するラベル ID を定義します。

classNames = ["triangle","background"];
labelIDs   = [255 0];

各テスト イメージのグラウンド トゥルース ラベルを読み取ります。各グラウンド トゥルース ラベルから blockedImage オブジェクトを作成します。

for idx = 1:numImages
    gtLabel = imread(fullfile(testLabelsDir,['labeled_image_' '00' num2str(idx) '.png']));
    gtLabel = imresize(gtLabel,4,'nearest');
    groundTruthImages(idx) = blockedImage(gtLabel);
end

最初のグラウンド トゥルース イメージを表示します。

bigimageshow(groundTruthImages(1))

テスト イメージごとに、関数 apply を使用して各ブロックを処理します。関数 apply は、この例の最後で定義されている補助関数 segmentAndCalculateBlockMetrics で指定された演算を実行します。関数は、各ブロックのセマンティック セグメンテーションを実行し、予測ラベルとグラウンド トゥルース ラベルの間の混同行列を計算します。

blockSize = [32 32];
datasetConfMat = table;
for idx = 1:numImages
    [segmentedImages(idx),blockConfMatOneImage] = apply(testImages(idx), ...
        @(block,labeledImageBlock) segmentAndCalculateBlockMetrics(block,labeledImageBlock,net,classNames,labelIDs), ...
        'ExtraImages',groundTruthImages(idx),'PadPartialBlocks',true,'BlockSize',blockSize,'UseParallel',false);

    % Read all the block results of an image and update the image number
    blockConfMatOneImageDS = blockedImageDatastore(blockConfMatOneImage);
    blockConfMat = readall(blockConfMatOneImageDS);
    blockConfMat = struct2table([blockConfMat{:}]);
    blockConfMat.ImageNumber = idx.*ones(height(blockConfMat),1);
    datasetConfMat = [datasetConfMat;blockConfMat];
end

最初にセグメント化されたイメージを表示します。

bigimageshow(segmentedImages(1))

セグメンテーションのデータ セット メトリクスとブロック メトリクスを評価します。

[metrics,blockMetrics] = evaluateSemanticSegmentation(datasetConfMat,classNames,'Metrics','all');
Evaluating semantic segmentation results
----------------------------------------
* Selected metrics: global accuracy, class accuracy, IoU, weighted IoU.
* Processed 3 images.
* Finalizing... Done.
* Data set metrics:

    GlobalAccuracy    MeanAccuracy    MeanIoU    WeightedIoU
    ______________    ____________    _______    ___________

       0.95428          0.82739       0.69927      0.92533  

すべてのイメージの Jaccard スコアを計算します。

jaccardSimilarity = metrics.ImageMetrics.MeanIoU
jaccardSimilarity = 3×1

    0.7664
    0.7277
    0.6538

サポート対象の関数

関数 segmentAndCalculateBlockMetrics は、単一ブロックのセマンティック セグメンテーションを実行してから、予測ラベルとグラウンド トゥルース ラベルの混同行列を計算します。

function [outputLabeledImageBlock,blockConfMatPerBlock] = segmentAndCalculateBlockMetrics(block,labeledImageBlock,net,classNames,labelIDs)

    outputLabeledImageBlock = semanticseg(block.Data,net);
    
    % Convert the ground truth labels to categorical
    labeledImageBlock = categorical(labeledImageBlock,labelIDs,classNames);
    confusionMatrix = segmentationConfusionMatrix(outputLabeledImageBlock,labeledImageBlock);
    
    % blockConfMatPerBlock is a struct with confusion matrices, image number
    % and blockInfo. Use the struct with evaluateSemanticSegmentation to
    % calculate metrics and aggregate block-based results.
    blockConfMatPerBlock.ConfusionMatrix = confusionMatrix;
    blockConfMatPerBlock.ImageNumber = block.ImageNumber;
    
    blockInfo.Start = block.Start;
    blockInfo.End = block.End;
    blockConfMatPerBlock.BlockInfo = blockInfo;
end

参考

| | | |

関連する例

詳細