В этом примере показано, как создать tform структура, которая представляет простое преобразование сдвига, а затем применяет его к изображению. Мы исследуем, как преобразование влияет на прямые линии и круги, а затем используем его как средство для изучения различных вариантов заполнения изображения, которые можно использовать с imtransform и tformarray.
В двух измерениях простое преобразование сдвига, отображающее пару входных координат [u v] к паре выходных координат [x y] имеет форму
a * v
v
где 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. Существует в общей сложности пять различных вариантов метода pad ('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''');