exponenta event banner

Одновременное заполнение и разрезание изображения

В этом примере показано, как создать tform структура, которая представляет простое преобразование сдвига, а затем применяет его к изображению. Мы исследуем, как преобразование влияет на прямые линии и круги, а затем используем его как средство для изучения различных вариантов заполнения изображения, которые можно использовать с 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

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

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' (циклическое повторение изображения с добавленным зеркальным отображением). Чтобы показать больше вырисовывающегося узора, мы переопределяем преобразование, чтобы сократить масштаб пополам.

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.