В этом примере показано, как создать tform struct, которая представляет простое преобразование сдвига и затем применяет его к изображению. Мы исследуем, как преобразование влияет на прямые линии и круги, а затем используем его как транспортное средство, чтобы исследовать различные опции заполнения изображений, которые могут использоваться с imtransform и tformarray.
В две размерностей простое преобразование сдвига, которое отображает пару входа координат [u v] к паре выхода координат [x y] имеет форму
где a является константой.
Любой простой сдвиг является частным случаем аффинного преобразования. Вы можете легко проверить, что
приводит к значениям для x и y что вы получили от первых двух уравнений.
Настройка a = 0,45, мы создадим аффин tform struct с использованием maketform.
a = 0.45;
T = maketform('affine', [1 0 0; a 1 0; 0 0 1] );Мы выбираем, читаем, и просматриваем, и изображение для преобразования.
A = imread('football.jpg'); h1 = figure; imshow(A); title('Original Image');

Мы выбираем оттенок оранжевого цвета в качестве значения.
orange = [255 127 0]';
Мы готовы использовать T для преобразования A. Мы можем позвонить imtransform следующим образом:
B = imtransform(A,T,'cubic','FillValues',orange);
но это расточительно, поскольку мы применяли бы кубическую интерполяцию как по столбцам, так и по строкам. (С нашим чистым преобразованием сдвига, нам действительно нужно только интерполироваться вдоль каждой строки.) Вместо этого мы создаем и используем ресамплер, который применяет кубическую интерполяцию вдоль строк, но просто использует ближайшую соседнюю интерполяцию вдоль столбцов, затем вызывает imtransform и отобразите результат.
R = makeresampler({'cubic','nearest'},'fill');
B = imtransform(A,T,R,'FillValues',orange);
h2 = figure; imshow(B);
title('Sheared Image');
Преобразование сетки прямых линий или массива кругов с tformfwd является хорошим способом понять преобразование (пока оно имеет как прямые, так и обратные функции).
Задайте сетку линий, покрывающих оригинальное изображение, и отобразите ее над изображением Затем используйте tformfwd чтобы применить чистый сдвиг к каждой линии в сетке и отобразить результат на срезанном изображении.
[U,V] = meshgrid(0:64:320,0:64:256); [X,Y] = tformfwd(T,U,V); gray = 0.65 * [1 1 1]; figure(h1); hold on; line(U, V, 'Color',gray); line(U',V','Color',gray);

figure(h2); hold on; line(X, Y, 'Color',gray); line(X',Y','Color',gray);

То же самое можно сделать с массивом кругов.
gray = 0.65 * [1 1 1]; for u = 0:64:320 for v = 0:64:256 theta = (0 : 32)' * (2 * pi / 32); uc = u + 20*cos(theta); vc = v + 20*sin(theta); [xc,yc] = tformfwd(T,uc,vc); figure(h1); line(uc,vc,'Color',gray); figure(h2); line(xc,yc,'Color',gray); end end


Когда мы применили преобразование сдвига, imtransform заполнены оранжевые треугольники слева и справа, где данных не было. Это потому, что мы задали метод pad для 'fill' при вызове makeresampler. Существует в общей сложности пять различных вариантов метода заполнения ('fill', 'replicate', 'bound', 'circular', и 'symmetric'). Здесь мы сравниваем первые три.
Во-первых, чтобы лучше взглянуть на то, как 'fill' опция сработала, используйте 'XData' и 'YData' опции в imtransform чтобы форсировать некоторое дополнительное пространство вокруг выходного изображения.
R = makeresampler({'cubic','nearest'},'fill');
Bf = imtransform(A,T,R,'XData',[-49 500],'YData',[-49 400],...
'FillValues',orange);
figure, imshow(Bf);
title('Pad Method = ''fill''');
Теперь попробуйте 'replicate' метод (не нужно задавать значения заливки в этом случае).
R = makeresampler({'cubic','nearest'},'replicate');
Br = imtransform(A,T,R,'XData',[-49 500],'YData', [-49 400]);
figure, imshow(Br);
title('Pad Method = ''replicate''');
И попробуйте 'bound' способ.
R = makeresampler({'cubic','nearest'}, 'bound');
Bb = imtransform(A,T,R,'XData',[-49 500],'YData',[-49 400],...
'FillValues',orange);
figure, imshow(Bb);
title('Pad Method = ''bound''');
Результаты с 'fill' и 'bound' выглядите очень похожи, но присмотритесь и вы увидите, что ребра более гладкие с 'fill'. Это потому, что вход изображение заполнено значениями заливки, тогда кубическая интерполяция применяется через ребро, смешивая значения заливки и изображения. Напротив, 'bound' распознает строгий контур между внутренней и внешней частями входа изображения. Точки, падающие снаружи, заполняются. Точки, падающие внутрь, интерполируются, используя репликацию, когда они находятся рядом с ребром. Внешний вид помогает показать это более четко. Выбираем XData и YData чтобы скобить точку рядом с нижним правым углом изображения, в выходное изображение пространстве, измените размер с 'nearest' для сохранения внешнего вида отдельных пикселей.
R = makeresampler({'cubic','nearest'},'fill');
Cf = imtransform(A,T,R,'XData',[423 439],'YData',[245 260],...
'FillValues',orange);
R = makeresampler({'cubic','nearest'},'bound');
Cb = imtransform(A,T,R,'XData',[423 439],'YData',[245 260],...
'FillValues',orange);
Cf = imresize(Cf,12,'nearest');
Cb = imresize(Cb,12,'nearest');
figure;
subplot(1,2,1); imshow(Cf); title('Pad Method = ''fill''');
subplot(1,2,2); imshow(Cb); title('Pad Method = ''bound''');
Оставшиеся два метода заполнения 'circular' (циклическое повторение в каждой размерности) и 'symmetric' (циклическое повторение изображения с добавленным зеркальным изображением). Чтобы показать больше шаблона, который появляется, мы переопределяем преобразование, чтобы сократить шкалу вдвое.
Thalf = maketform('affine',[1 0; a 1; 0 0]/2); R = makeresampler({'cubic','nearest'},'circular'); Bc = imtransform(A,Thalf,R,'XData',[-49 500],'YData',[-49 400],... 'FillValues',orange); figure, imshow(Bc); title('Pad Method = ''circular''');

R = makeresampler({'cubic','nearest'},'symmetric');
Bs = imtransform(A,Thalf,R,'XData',[-49 500],'YData',[-49 400],...
'FillValues',orange);
figure, imshow(Bs);
title('Pad Method = ''symmetric''');