Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

マスクを使用した大きなイメージの効率的な処理

この例では、マスクを使用して ROI を分離することによって、大きなイメージを効率的に処理する方法を説明します。

大きなイメージのソースのなかには、イメージのごく一部にのみ意味のあるデータが含まれているものがあります。意味のあるデータが含まれる関心領域 (ROI) に処理を制限することにより、合計処理時間を改善できます。マスクを使用して ROI を定義します。マスクは、true ピクセルが ROI を表す論理イメージです。

bigimage のワークフローでは、マスクはイメージ データと同じ空間領域を表しますが、イメージと同じサイズである必要はありません。ワークフローの効率をさらに向上させるには、粗いイメージからマスクを、特にメモリに収まるものを作成します。その後、粗いマスクを使用して、より細かいイメージを処理します。

CAMELYON16 データセットのイメージ "tumor_091.tif" の変更したバージョンを使用して bigimage を作成します。元のイメージは、腫瘍組織が含まれるリンパ節の学習イメージです。元のイメージには 8 つの解像度レベルがあり、最も細かいレベルの解像度は 53760 x 61440 です。変更したイメージには、3 つの粗い解像度レベルのみが含まれています。変更したイメージの空間参照は、縦横比が一定に維持され、各レベルで特徴がレジストレーションされるように調整されています。

bim = bigimage('tumor_091R.tif');

関数 bigimageshow を使用して大きなイメージを表示します。

bigimageshow(bim);

マスクの作成

最も粗いレベルのイメージ サイズを決定します。

coarseLevel = bim.CoarsestResolutionLevel;
coarseLevelSize = bim.LevelSizes(coarseLevel,:)
coarseLevelSize = 1×2

   625   670

最も粗い解像度レベルのイメージを取得します。

imLowRes = bim.getFullLevel(bim.CoarsestResolutionLevel);

イメージの領域分割アプリを使用して、粗いレベルからマスクを生成できます。アプリはグレースケール入力イメージを想定しているため、粗いイメージから輝度チャネルを取得します。

imLowResL = rgb2lightness(imLowRes);

イメージの領域分割アプリを実行するには、コマンド ウィンドウで次のコマンドを入力します。

imageSegmenter(imLowResL)

マスク BW をエクスポートしたり、マスクを作成するために使用する処理パイプラインを再現するコードをエクスポートしたりすることができます。この節では、アプリでエクスポートしたコードを使用してこの例を扱います。次のコードを実行して、粗い入力イメージからマスクを作成します。

%----------------------------------------------------
% Normalize input data to range in [0,1].
Xmin = min(imLowResL(:));
Xmax = max(imLowResL(:));
if isequal(Xmax,Xmin)
    imLowResL = 0*imLowResL;
else
    imLowResL = (imLowResL - Xmin) ./ (Xmax - Xmin);
end

% Threshold image - global threshold
BW = imbinarize(imLowResL);

% Invert mask
BW = imcomplement(BW);

% Open mask with square
width = 3;
se = strel('square', width);
BW = imopen(BW, se);
%----------------------------------------------------

imshow(BW)

入力マスクと同じ空間参照を使用して、このマスクから bigimage を作成します。

bmask = bigimage(BW, ...
    'SpatialReferencing',bim.SpatialReferencing(coarseLevel));

緑色の背景を使用してマスクを表示します。

h = bigimageshow(bim);
h.Parent.Color = 'g';
h.Parent.Alphamap = [1 .5];
h.AlphaData = bmask;
h.AlphaDataMapping = 'direct';

包含しきい値の調整による関心領域のカバー

関数 apply は大きなイメージを一度に 1 ブロックずつ処理します。'InclusionThreshold' プロパティをマスクと共に使用して、関数 apply が使用するブロックを指定できます。包含しきい値は、apply がブロックを処理するために true でなければならないマスク ピクセルの割合を指定します。

apply が既定の包含しきい値 0.5 を使用して処理するブロックを強調表示します。緑色に強調表示された中央のブロックのみが処理されます。

h = bigimageshow(bim);
showmask(h,bmask,1);
title('Mask with Default Inclusion Threshold')

イメージ内のより多くのブロックを処理するには、包含しきい値を減らします。

showmask(h,bmask,1,'InclusionThreshold',0.4);
title('InclusionThreshold == 0.4')

極端なケースでは、マスク内に true ピクセルが少なくとも 1 つ含まれるすべてのブロックを処理します。このオプションを指定するには、'InclusionThreshold' プロパティを 0 に設定します。必ずしもイメージ内のすべてのブロックが含まれるわけではありません。

showmask(h,bmask,1,'InclusionThreshold',0);
title('InclusionThreshold == 0')

任意の値の 'InclusionThreshold' を指定してマスクを使用すると、apply は、フル イメージよりも少ない数のブロックを処理するため、合計実行時間が減少します。イメージの解像度が大きいほど、また処理パイプラインが複雑であるほど、マスクを使用するメリットが著しくなります。

フル イメージに対するフィルター処理の実行時間を測定します。

tic
bout = apply(bim,1, ...
    @(block)imnlmfilt(block,'DegreeOfSmoothing',15));
tFullProcessing = toc;

ROI を含むブロックのみに対するフィルター処理の実行時間を測定します。

tic
boutMasked = apply(bim,1, ...
    @(block)imnlmfilt(block,'DegreeOfSmoothing',15), ...
    'Mask',bmask,'InclusionThreshold',0);
tMaskedProcessing = toc;

bigimageshow(boutMasked)
defaultBlockSize = bim.BlockSize(1,:);
title(['Processed Image Using Mask with Default BlockSize == [' ...
    num2str(defaultBlockSize) ']']);

フル イメージの処理の実行時間を ROI のブロックのみの処理と比較します。

disp(['Speedup using mask: ' ...
    num2str(tFullProcessing/tMaskedProcessing) 'x']);
Speedup using mask: 1.6817x

ブロック サイズの調整による関心領域の輪郭の追従

ブロック サイズを減らすと、ROI をより厳密に囲むことができます。ブロック サイズによっては、apply が処理する ROI 外のピクセル数が少なくなるため、これにより実行時間が減少します。ただし、ブロック サイズが小さすぎると、大量のブロックを処理するためのオーバーヘッドが処理ピクセル数の減少を相殺するため、パフォーマンスが低下します。

apply が小さいブロック サイズを使用して処理するブロックを強調表示します。ブロック サイズを指定するには、'BlockSize' プロパティを設定します。

blockSize = [512 512];
h = bigimageshow(bim);
showmask(h,bmask,1,'BlockSize',blockSize,'InclusionThreshold',0);
title(['BlockSize == [' num2str(blockSize) '], InclusionThreshold == 0'])

ブロック サイズを減らした場合の ROI 内の全ブロックに対するフィルター処理の実行時間を測定します。

tic
boutMasked = apply(bim,1, ...
    @(block)imnlmfilt(block,'DegreeOfSmoothing',15), ...
    'Mask',bmask,'BlockSize',blockSize,'InclusionThreshold',0);
tSmallerBlockProcessing = toc;

bigimageshow(boutMasked);
title(['Processed Image Using Mask with BlockSize == [' ...
    num2str(blockSize) ']']);

小さいブロックの場合の ROI 全体に対する処理の実行時間を大きなブロックの場合と比較します。

disp(['Additional speedup using mask with decreased block size: ' ...
    num2str(tMaskedProcessing/tSmallerBlockProcessing) 'x']);
Additional speedup using mask with decreased block size: 1.3684x

参考

| |