Создайте пометил bigimage от ROI и масок

В этом примере показано, как создать помеченный bigimage состоя из категориальных меток.

Существует несколько способов задать категориальные данные о метке для изображения. Этот пример показывает два подхода. Один подход использует многоугольные объекты ROI, которые хранят координаты контуров опухоли и нормальной ткани. Другой подход использует маску, чтобы указать на бинарную сегментацию изображения в ткань и фон. Пример комбинирует информацию в координатах многоугольника, и представления маски, чтобы создать сингл пометили bigimage.

Создайте bigimage использование модифицированной версии изображения "tumor_091.tif" от набора данных CAMELYON16. Оригинальное изображение является учебным изображением лимфатического узла, содержащего ткань опухоли. Оригинальное изображение имеет восемь уровней разрешения, и самый прекрасный уровень имеет разрешение 53760 61440. Модифицированное изображение имеет только три крупных уровня разрешения. Пространственная ссылка модифицированного изображения была настроена, чтобы осуществить сопоставимое соотношение сторон и указать функции на каждом уровне.

bim = bigimage('tumor_091R.tif');

Получите пространственную ссылку и пиксельную степень bigimage на желаемом уровне на выходе.

ref = bim.SpatialReferencing(bim.FinestResolutionLevel);
pixelExtent = [ref.PixelExtentInWorldX,ref.PixelExtentInWorldY];

Загрузите данные о метке

Набор данных CAMELYON16 обеспечивает метки опухоли и нормальных областей как набор координат, задающих вручную аннотируемые контуры области относительно самого прекрасного уровня разрешения. Когда пиксели существуют в контурах и нормальной области и области опухоли, правильная метка для тех пикселей является нормальной тканью.

Загрузите данные о метке для большого изображения. Этот пример использует модифицированную версию меток изображения "tumor_091.tif" от набора данных CAMELYON16. Исходные метки хранятся в формате XML. Модифицированные метки передискретизируются и сохранены как файлы MAT.

roiPoints = load('labelledROIs.mat')
roiPoints = struct with fields:
       cancerRegions: {[344×2 double]  [53×2 double]  [539×2 double]  [247×2 double]  [37×2 double]  [161×2 double]}
    nonCancerRegions: {[46×2 double]}

Создайте многоугольные объекты ROI, которые хранят координаты контуров опухоли и нормальных контуров ткани.

tumorPolys = cellfun(@(position) images.roi.Polygon( ...
    'Position',position,'Visible','on','Color','r'), ...
    roiPoints.cancerRegions);
normalPolys = cellfun(@(position) images.roi.Polygon( ...
    'Position',position,'Visible','on','Color','g'), ...
    roiPoints.nonCancerRegions);

Представляйте метки, в то время как ROI возражает

Отобразите изображение, наложенное с аннотируемыми ROI. ROI имеют ту же систему координат, как изображение, таким образом изменяя уровни разрешения отображенного изображения все еще представляет ROI точно.

figure
h = bigimageshow(bim);
set(tumorPolys,'Parent',gca);
set(normalPolys,'Parent',gca);
title(['Resolution Level:' num2str(h.ResolutionLevel)]);

Увеличьте масштаб к одному ROI.

xlim([3940 4290])
ylim([2680 3010])
title(['Resolution Level:' num2str(h.ResolutionLevel)]);

Представляйте метки как маски

Создайте маску на самом грубом уровне разрешения для запятнанной области, которая включает и опухоль и нормальную ткань. Маской является 1 TRUE) для пикселей, полутоновое значение которых меньше 130. Заполните маленькие отверстия в маске путем выполнения морфологического закрытия с помощью bwmorph функция.

tissueMask = apply(bim,bim.CoarsestResolutionLevel, ...
    @(im)bwmorph(rgb2gray(im)<130,'close'));
bigimageshow(tissueMask);

Создайте объединенный, пометил bigimage

Объедините информацию в координатах многоугольника, и представления маски, чтобы создать сингл пометили bigmage.

Чтобы сохранить помеченное изображение, создайте writeable bigimage с категориальным типом данных. Укажите, что необходимые имена классов и соответствующий числовой пиксель помечают Значения идентификаторов. Присвойте метку 0 'Фоновому' классу. Присвойте значение метке 'UndefinedID', которая не равняется ни одной пиксельной метке IDs.

blockSize = [512 512];
bLabeled = bigimage(ref,1,'categorical', ...
    'Classes',["Background","Normal","Tumor"], ...
    'PixelLabelIDs',[0 1 2], ...    
    'UndefinedID',255, ...
    'BlockSize',blockSize);

Цикл посредством каждого выхода bigimage, один блок за один раз. Определите метку каждого блока, затем установите пиксельные данные блока соответственно.

Чтобы определить метку каждого блока, начните с маски всей ткани. Пиксельные значения 0 в маске соответствуют фону, который совпадает с пиксельной меткой ID 'Фонового' класса. Пиксельные значения 1 в маске соответствуют всей ткани, которая совпадает с пиксельной меткой ID класса 'Normal'. Преобразуйте координаты многоугольника ткани опухоли к маске при помощи poly2mask функция, затем замените те пиксели на пиксельную метку ID класса 'Опухоли', 2.

Если у вас есть Parallel Computing Toolbox™, то можно запустить цикл параллельно, заменив for оператор с parfor оператор.

for cStart = 1:bLabeled.BlockSize(2):ref.ImageSize(2)
    for rStart = 1:bLabeled.BlockSize(1):ref.ImageSize(1)
        % Find the center of top left pixel of the block in world units
        xyStart = [cStart, rStart].*pixelExtent;
        
        % Clamp block edges to the border of the image
        cEnd = min(cStart + bLabeled.BlockSize(2)-1,ref.ImageSize(2));
        rEnd = min(rStart + bLabeled.BlockSize(1)-1,ref.ImageSize(1));
        
        % Find the center of bottom right pixel of the block in world units
        xyEnd = [cEnd rEnd].*pixelExtent;
        
        % Calculate the block size
        bsize = [rEnd cEnd] - [rStart cStart] + 1;
        
        % Create a grid encompassing all pixels in the block.
        [xgrid,ygrid] = meshgrid(xyStart(1):ref.PixelExtentInWorldX:xyEnd(1), ...
            xyStart(2):ref.PixelExtentInWorldY:xyEnd(2));
        
        % Get the mask of all tissue in the block
        blockNumeric = getRegion(tissueMask,1,xyStart,xyEnd);        
        % This tissue mask was created at a coarse level, so scale it up
        blockNumeric = imresize(blockNumeric,bsize);

        % Find the pixel coordinates of healthy tissue then convert the
        % polygon coordinates to a mask.
        tmask = false(bsize);
        for ind = 1:numel(roiPoints.cancerRegions)
            vertices = roiPoints.cancerRegions{ind};
            % Transform coordinates to local block pixel locations
            vertices = (vertices-xyStart)./pixelExtent+1;
            isTumor = poly2mask(vertices(:,1),vertices(:,2), ...
                bsize(1), bsize(2));
            tmask = tmask|isTumor;
        end
        
        % Some healthy tissue ROIs are enclosed within a tumor ROI. Find
        % the pixel coordinates of healthy tissue then convert the polygon
        % coordinates to a mask.
        for ind = 1:numel(roiPoints.nonCancerRegions)
            vertices = roiPoints.nonCancerRegions{ind};
            % Transform coordinates to local block pixel locations
            vertices = (vertices-xyStart)./pixelExtent+1;
            isHealthy = poly2mask(vertices(:,1),vertices(:,2), ...
                bsize(1),bsize(2));
            tmask = tmask & ~isHealthy;
        end        
        
        % Set the value of pixels in tumor regions as the corresponding
        % pixel label ID, |2|.
        blockNumeric = uint8(blockNumeric);
        blockNumeric(tmask) = 2;
        
        % Create a categorical image from the block data.
        blockCategorical = categorical(blockNumeric,...
            bLabeled.PixelLabelIDs,bLabeled.Classes);
        
        % Set the block of the categorical |bigimage| as the categorical
        % block image.
        setBlock(bLabeled,1,xyStart,blockCategorical);
    end
end

Отобразите наложение меток и исходных данных

Отобразите данные изображения, затем отобразите помеченные данные изображения в тех же осях. Три метки (нормальный, опухоль и фон) появляются в трех различных цветах. Сделайте метки частично прозрачными так, чтобы можно было отличить содержимое изображения внизу.

hbim = bigimageshow(bim);
hla = axes;
hbl  = bigimageshow(bLabeled,'Parent',hla);
hbl.AlphaData = 0.7;
hla.Visible = 'off';

Увеличьте масштаб к ROI. Увеличьте прозрачность метки так, чтобы можно было более ясно отличить содержимое изображения внизу.

linkaxes(findall(gcf,'Type','axes'));
xlim([3940 4290])
ylim([2680 3010])
hbl.AlphaData = 0.3;

Сохраните метки для использования позже

Для большинства наборов данных можно создать метки однажды и затем снова использовать метки для нескольких сеансов обучения. Помеченное большое изображение, bLabeled, поддерживается временными файлами, которые не существуют через сеансы MATLAB®. Чтобы снова использовать метки на различном сеансе MATLAB, запишите bLabeled к персистентному местоположению.

imageDir = 'Labels';
if exist(imageDir,'dir')
    rmdir('Labels','s');
end
labelDir = fullfile(imageDir,'labelled');
write(bLabeled,labelDir);

На новой сессии MATLAB можно перезагрузить помеченный bigimage путем создания нового bigimage. При загрузке помеченного bigimage, необходимо также задать 'Классы', 'PixelLabelIDs' и 'UndefinedID'.

bLabeled = bigimage(labelDir, ...
    'PixelLabelIDs',[ 0 1 2],'Classes',["Background","Normal","Tumor"], ...
    'UndefinedID',255);

Смотрите также

| |

Похожие темы