В этом примере показано, как применить геометрическое преобразование (деформирующееся) к блокированному изображению.
Применение геометрического преобразования к изображению является ключевым шагом во многих приложениях для обработки изображений как регистрация изображений. Можно использовать imwarp
деформировать крупные изображения, которые умещаются в памяти. Для больших, изображений с высоким разрешением, которые не умещаются в памяти, используйте блокированное изображение. Установите пространственную ссылку деформированного изображения сохранять характеристики изображения, такие как пиксельные степени.
Создайте блокированное изображение с помощью модифицированной версии изображения "tumor_091.tif" от набора данных CAMELYON16. Оригинальное изображение является учебным изображением лимфатического узла, содержащего ткань опухоли. Оригинальное изображение имеет восемь уровней разрешения, и самый прекрасный уровень имеет разрешение 53760 61440. Модифицированное изображение имеет только три крупных уровня разрешения. Пространственная ссылка модифицированного изображения была настроена, чтобы осуществить сопоставимое соотношение сторон и указать функции на каждом уровне.
bim = blockedImage('tumor_091R.tif');
Создайте affine2d
объект, который хранит информацию об аффинном геометрическом преобразовании. Это преобразование применяет перевод и сдвиг.
tform = affine2d([ 0.99 0.01 0 0.17 0.98 0 120 -30 1]);
Получите изображение на самом грубом уровне разрешения.
imCoarse = gather(bim);
Деформируйте крупное изображение при помощи imwarp
. Отобразите оригинальное изображение и деформированное изображение в монтаже.
imCoarseWarped = imwarp(imCoarse,tform); figure imshow(imCoarseWarped)
Прежде, чем применить геометрическое преобразование к изображению на уровне высокого разрешения, вычислите пространственную ссылку блокированного изображения после деформирования. Используйте эту пространственную ссылку при преобразовании блоков
Получите пиксельную степень оригинального изображения от его пространственной информации о ссылке.
inPixelExtent = (bim.WorldEnd(1,:)-bim.WorldStart(1,:))./bim.Size(1,:);
Вычислите выходную горизонталь и вертикальные пространственные пределы, когда преобразование будет применено.
yWorldLimits = [bim.WorldStart(1,1), bim.WorldEnd(1,1)]; xWorldLimits = [bim.WorldStart(1,2), bim.WorldEnd(1,2)]; [xout, yout] = outputLimits(tform,xWorldLimits,yWorldLimits);
Вычислите размер выходного изображения, которое сохраняет пиксельную степень. Задайте размер изображения в формате [numrows, numcols].
outImgSize = [ceil(diff(yout)/inPixelExtent(1)),...
ceil(diff(xout)/inPixelExtent(2))];
Храните пространственную информацию ссылки деформированного изображения. Установите мировые пределы и размер изображения деформированного изображения.
outWorldStart = [yout(1),xout(1)]; outWorldEnd = [yout(2), xout(2)];
Вычислите соответствующие размерности выходного пикселя.
outPixelExtent = (outWorldEnd-outWorldStart)./outImgSize; halfPixWidth = outPixelExtent/2;
Создайте перезаписываемое блокированное изображение путем указывания выхода пространственная информация ссылки. Задайте размер блока, который является достаточно большим, чтобы использовать память эффективно.
outBlockSize = [1024 1024 3]; bwarped = blockedImage([],[outImgSize 3],outBlockSize,uint8(0),... 'Mode','w',... 'WorldStart', [yout(1), xout(1)],... 'WorldEnd', [yout(2), xout(2)]);
Цикл через выходное изображение, один блок за один раз. Для каждого выходного блока:
Найдите координаты четырех углов выходного блока.
Обратная карта эти координаты назад к входу, чтобы получить вход (источник) область.
Считайте содержимое входной области.
Создайте пространственную ссылку, описывающую входную область.
Вычислите выходное содержимое блока при помощи imwarp
.
Запишите выходной блок в выходное изображение при помощи setBlock
функция.
Если у вас есть Parallel Computing Toolbox™, то можно заменить внешний for
оператор с parfor
оператор, чтобы запустить цикл параллельно.
inYWorldLimits = [bim.WorldStart(1,1), bim.WorldEnd(1,1)]; inXWorldLimits = [bim.WorldStart(1,2), bim.WorldEnd(1,2)]; for rBlockInd = 1:bwarped.SizeInBlocks(1) for cBlockInd = 1:bwarped.SizeInBlocks(2) blockSub = [rBlockInd, cBlockInd 1]; % Center of top left pixel of this block in world units blockStartSub = blocksub2sub(bwarped, blockSub); blockStartWorld = sub2world(bwarped, blockStartSub); % Center of bottom right pixel of this block in world units blockEndSub = blockStartSub + outBlockSize - 1; blockEndWorld = sub2world(bwarped, blockEndSub); % Spatial reference which describes this block (Note: spatial % referencing is in x-y order, while blockStart etc are in y-x % order). Ensure to move the region outwards by half a pixel to % reference the outer edge of this block. outRegionRef = imref2d(fliplr(outBlockSize(1:2))); outRegionRef.YWorldLimits = [blockStartWorld(1)-halfPixWidth(1),... blockEndWorld(1)+halfPixWidth(1)]; outRegionRef.XWorldLimits = [blockStartWorld(2)-halfPixWidth(2),... blockEndWorld(2)+halfPixWidth(2)]; % Output bounding box in world coordinates outbbox = [ fliplr(blockStartWorld(1:2)) blockStartWorld(2) blockEndWorld(1) blockEndWorld(2) blockStartWorld(1) fliplr(blockEndWorld(1:2))]; % Get corresponding input region. Note: This region need NOT be % rectangular if the transformation includes shear inRegion = transformPointsInverse(tform,outbbox); % Clamp region to image extents inRegion(:,2) = max(inRegion(:,2),inYWorldLimits(1)); inRegion(:,2) = min(inRegion(:,2),inYWorldLimits(2)); inRegion(:,1) = max(inRegion(:,1),inXWorldLimits(1)); inRegion(:,1) = min(inRegion(:,1),inXWorldLimits(2)); % Find the corresponding input bounding box inbboxStart = [min(inRegion(:,1)) min(inRegion(:,2))]; inbboxEnd = [max(inRegion(:,1)) max(inRegion(:,2))]; % Move to y-x (row-col) order inbboxStart = fliplr(inbboxStart); inbboxEnd = fliplr(inbboxEnd); % Convert to pixel subscripts inbboxStartSub = world2sub(bim, [inbboxStart 1]); inbboxEndSub = world2sub(bim, [inbboxEnd 3]); % Read corresponding input region inputRegion = getRegion(bim,inbboxStartSub,inbboxEndSub); % Input region's spatial referencing inRegionRef = imref2d(size(inputRegion)); % Convert the actual region pixel's centers back to world % coordinates. inbboxStart = sub2world(bim, inbboxStartSub); inbboxEnd = sub2world(bim, inbboxEndSub); % Convert to pixel edges from pixel centers inRegionRef.YWorldLimits = [inbboxStart(1)-halfPixWidth(1),... inbboxEnd(1)+halfPixWidth(2)]; inRegionRef.XWorldLimits = [inbboxStart(2)-halfPixWidth(1),... inbboxEnd(2)+halfPixWidth(2)]; % Warp this block warpedBlock = imwarp(inputRegion,inRegionRef,tform,'OutputView',outRegionRef); % Set the block data in the output blocked image setBlock(bwarped,blockSub,warpedBlock); end end
Отобразите деформированное изображение.
bwarped.Mode = 'r';
figure
bigimageshow(bwarped)
blockedImage
| bigimageshow
| setBlock
| affine2d
| imref2d
| transformPointsInverse
| getRegion