В этом примере показано, как применить геометрическое преобразование (деформирование) к заблокированному изображению.
Применение геометрического преобразования к изображению является ключевым этапом во многих приложениях обработки изображения, таких как регистрация изображения. Вы можете использовать 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 функция.
При наличии Toolbox™ Parallel Computing можно заменить внешний 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)
affine2d | bigimageshow | blockedImage | getRegion | imref2d | setBlock | transformPointsInverse