Заполнение и качание изображения одновременно

В этом примере показано, как создать tform struct, которая представляет простое преобразование сдвига и затем применяет его к изображению. Мы исследуем, как преобразование влияет на прямые линии и круги, а затем используем его как транспортное средство, чтобы исследовать различные опции заполнения изображений, которые могут использоваться с imtransform и tformarray.

Шаг 1: Преобразование изображения с помощью простого сдвига

В две размерностей простое преобразование сдвига, которое отображает пару входа координат [u v] к паре выхода координат [x y] имеет форму

x=u+a*v

y=v

где a является константой.

Любой простой сдвиг является частным случаем аффинного преобразования. Вы можете легко проверить, что

[xy1]=[uv1]*[100a10001]

приводит к значениям для 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');

Figure contains an axes. The axes with title Original Image contains an object of type 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');

Figure contains an axes. The axes with title Sheared Image contains an object of type image.

Шаг 2: Исследуйте Преобразование

Преобразование сетки прямых линий или массива кругов с 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 contains an axes. The axes with title Original Image contains 12 objects of type image, line.

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

Figure contains an axes. The axes with title Sheared Image contains 12 objects of type image, line.

То же самое можно сделать с массивом кругов.

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

Figure contains an axes. The axes with title Original Image contains 42 objects of type image, line.

Figure contains an axes. The axes with title Sheared Image contains 42 objects of type image, line.

Шаг 3: Сравните 'fill', 'replicate' и 'bound' Pad Methods

Когда мы применили преобразование сдвига, 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''');

Figure contains an axes. The axes with title Pad Method = 'fill' contains an object of type image.

Теперь попробуйте 'replicate' метод (не нужно задавать значения заливки в этом случае).

R = makeresampler({'cubic','nearest'},'replicate');
Br = imtransform(A,T,R,'XData',[-49 500],'YData', [-49 400]);

figure, imshow(Br);
title('Pad Method = ''replicate''');

Figure contains an axes. The axes with title Pad Method = 'replicate' contains an object of type image.

И попробуйте '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''');

Figure contains an axes. The axes with title Pad Method = 'bound' contains an object of type image.

Результаты с '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''');

Figure contains 2 axes. Axes 1 with title Pad Method = 'fill' contains an object of type image. Axes 2 with title Pad Method = 'bound' contains an object of type image.

Шаг 4: Упражнение 'circular' и 'symmetric' Pad Methods

Оставшиеся два метода заполнения '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''');

Figure contains an axes. The axes with title Pad Method = 'circular' contains an object of type image.

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''');

Figure contains an axes. The axes with title Pad Method = 'symmetric' contains an object of type image.