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 точно.
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);
bigimage
| bigimageDatastore
| bigimageshow