Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Relleno y corte de una imagen simultáneamente

En este ejemplo se muestra cómo construir una estructura que representa una transformación de corte simple y, a continuación, se aplica a una imagen.tform Exploramos cómo la transformación afecta a líneas rectas y círculos, y luego usarla como un vehículo para explorar las diversas opciones para el relleno de la imagen que se puede utilizar con y.imtransformtformarray

Paso 1: transforma una imagen usando simple cizallamiento

En dos dimensiones, una transformación de corte simple que asigna un par de coordenadas de entrada a un par de coordenadas de salida tiene la forma[u v][x y]

<math display="block">
<mrow>
<mi>x</mi>
<mo>=</mo>
<mi>u</mi>
<mo>+</mo>
<mi>a</mi>
<mo>*</mo>
<mi>v</mi>
</mrow>
</math>

<math display="block">
<mrow>
<mi>y</mi>
<mo>=</mo>
<mi>v</mi>
</mrow>
</math>

donde es una constante.a

Cualquier cizalla simple es un caso especial de una transformación afín. Puede verificar fácilmente que

<math display="block">
<mrow>
<mo stretchy="false">[</mo>
<mtable columnalign="center center">
<mtr>
<mtd>
<mrow>
<mi>x</mi>
<mspace width="0.5em"></mspace>
<mi>y</mi>
<mspace width="0.5em"></mspace>
<mn>1</mn>
</mrow>
</mtd>
</mtr>
</mtable>
<mo stretchy="false">]</mo>
<mo>=</mo>
<mo stretchy="false">[</mo>
<mtable columnalign="center center">
<mtr>
<mtd>
<mrow>
<mi>u</mi>
<mspace width="0.5em"></mspace>
<mi>v</mi>
<mspace width="0.5em"></mspace>
<mn>1</mn>
</mrow>
</mtd>
</mtr>
</mtable>
<mo stretchy="false">]</mo>
<mo>*</mo>
<mrow>
<mo>[</mo>
<mtable columnalign="center center center">
<mtr>
<mtd>
<mrow>
<mn>1</mn>
<mspace width="0.2777777777777778em"></mspace>
<mn>0</mn>
<mspace width="0.2777777777777778em"></mspace>
<mn>0</mn>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi>a</mi>
<mspace width="0.2777777777777778em"></mspace>
<mn>1</mn>
<mspace width="0.2777777777777778em"></mspace>
<mn>0</mn>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mn>0</mn>
<mspace width="0.2777777777777778em"></mspace>
<mn>0</mn>
<mspace width="0.2777777777777778em"></mspace>
<mn>1</mn>
</mrow>
</mtd>
</mtr>
</mtable>
<mo>]</mo>
</mrow>
</mrow>
</math>

produce los valores para y que recibió de las dos primeras ecuaciones.xy

Setting = 0,45, construimos una estructura afín usando.atformmaketform

a = 0.45; T = maketform('affine', [1 0 0; a 1 0; 0 0 1] );

Seleccionamos, leemos y vemos e imagen para transformar.

A = imread('football.jpg'); h1 = figure; imshow(A); title('Original Image');

Elegimos un tono de naranja como nuestro valor de relleno.

orange = [255 127 0]';

Estamos listos para usar para transformar.TUn Podríamos llamar de la siguiente manera:imtransform

B = imtransform(A,T,'cubic','FillValues',orange);

pero esto es inútil ya que aplicaría la interpolación cúbica a lo largo de las columnas y filas. (Con nuestra transformación de cizalla pura, realmente sólo necesitamos interpolar a lo largo de cada fila.) En su lugar, creamos y usamos un remuestreador que aplica la interpolación cúbica a lo largo de las filas, pero simplemente usa la interpolación de vecino más cercano a lo largo de las columnas, luego llama y muestra el resultado.imtransform

R = makeresampler({'cubic','nearest'},'fill'); B = imtransform(A,T,R,'FillValues',orange);  h2 = figure; imshow(B); title('Sheared Image');

Paso 2: explora la transformación

Transformar una cuadrícula de líneas rectas o una matriz de círculos con es una buena manera de entender una transformación (siempre y cuando tenga funciones tanto directas como inversas).tformfwd

Defina una rejilla de líneas que cubran la imagen original, y mostrarla sobre la imagen a continuación, utilízalos para aplicar la cizalla pura a cada línea de la rejilla y mostrar el resultado sobre la imagen esquiada.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);

Puede hacer lo mismo con una matriz de círculos.

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

Paso 3: Compare los métodos de almohadilla "Fill", "replicate" y "Bound"

Cuando aplicamos la transformación de cizalla, rellenamos los triángulos anaranjados a la izquierda y a la derecha, donde no había datos.imtransform Eso es porque especificamos un método Pad de cuando se llama.'fill'makeresampler Hay un total de cinco opciones de método de pad diferentes (,,,, y).'fill''replicate''bound''circular''symmetric' Aquí comparamos los tres primeros.

En primer lugar, para obtener un mejor vistazo a cómo funcionaba la opción, utilice las opciones y para forzar un espacio adicional alrededor de la imagen de salida.'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''');

Ahora, pruebe el método (no es necesario especificar los valores de relleno en este caso).'replicate'

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

Y prueba el método.'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''');

Resultados con y se ven muy similares, pero mira de cerca y verás que los bordes son más suaves con.'fill''bound''fill' Esto se debe a que la imagen de entrada se rellena con los valores de relleno, luego la interpolación cúbica se aplica a través del borde, mezclando los valores de relleno y de imagen. Por el contrario, reconoce un límite estricto entre el interior y el exterior de la imagen de entrada.'bound' Los puntos que caen afuera están llenos. Los puntos que caen dentro se interpolan, usando la replicación cuando están cerca del borde. Una mirada de cerca ayuda a mostrar esto con más claridad. Elegimos y cortamos un punto cerca de la esquina inferior derecha de la imagen, en el espacio de la imagen de salida, el cambio de tamaño con el fin de preservar la apariencia de los píxeles individuales.XDataYData'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''');

Paso 4: ejercitar los métodos de almohadilla ' circulares ' y ' simétricos '

Los dos métodos de pad restantes son (repetición circular en cada dimensión) y (repetición circular de la imagen con una imagen reflejada anexa).'circular''symmetric' Para mostrar más del patrón que emerge, redefinimos la transformación para cortar la escala por la mitad.

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