⚠️ Este é um site de tradução não oficial, sem relação com a ImageMagick Studio LLC. Para informações oficiais, consulte a página original (https://usage.imagemagick.org/distorts/index.html).

Exemplos do ImageMagick -- Distorcendo Imagens

Depois de examinar o conjunto simples de operadores internos de empacotamento e distorção de imagens que o IM fornece desde seus primeiros dias, aqui vamos mais fundo e observamos a mecânica interna e as distorções matemáticas mais complexas de imagens. A partir dessa compreensão mais profunda, examinamos então um operador de distorção de imagens mais generalizado. Isso inclui distorções, desde rotações complexas, escalonamento e cisalhamento, até distorções em perspectiva ou 3D, deformações de e para arcos circulares, distorções de lente de câmera e, por fim, distorções mais gerais no estilo de morphing.


Técnicas Gerais de Distorção

Agora que fomos apresentados aos operadores simples de distorção que o IM fornece, vamos dar um passo atrás e observar os detalhes essenciais, e ver como as distorções de imagem realmente funcionam, e como se pode melhorar a maneira de usá-las. Mais adiante avançaremos para formas muito mais complexas de distorcer imagens, incluindo métodos que não são diretamente embutidos no ImageMagick. Há apenas algumas maneiras básicas pelas quais um processador de imagens pode distorcer imagens. Os operadores de Distorção Simples, por exemplo, são obtidos por Troca de Pixels. Ou seja, pixels individuais ou mesmo linhas e colunas inteiras de pixels são simplesmente trocados de lugar para Espelhar, Rolar, Transpor e até Rotações Retangulares de imagens. Nenhuma alteração de cor é feita, e o número de pixels permanece o mesmo. O próximo método de distorcer imagens é por Deslocamento ou Cisalhamento das colunas e linhas de pixels, seja horizontal ou verticalmente, como o que o IM faz com o Cisalhamento de Imagem e a Distorção de Onda acima. Os cisalhamentos, por sua vez, fornecem um método para Rotacionar Imagens por qualquer ângulo dado, de uma forma que deve ser bastante rápida. No entanto, os métodos de deslocamento de pixels estão limitados a essas distorções básicas. Não é possível redimensionar uma imagem para um tamanho diferente, por exemplo. Também há muito pouco controle sobre o tratamento de áreas na imagem resultante que não foram cobertas pela imagem de origem original. Nas funções mencionadas acima, o IM apenas define as áreas ausentes com a cor de fundo atual. Para conseguir distorcer imagens de uma maneira muito mais geral, é preciso usar uma técnica de distorção mais geral conhecida como Mapeamento Reverso de Pixels. Por exemplo, esse método é usado pelas Distorções Circulares mais complexas, como imagens Implodindo e Redemoinhando.

Mapeamento de Pixels Adiante ou Direto

A primeira coisa que as pessoas pensam ao tentar distorcer uma imagem é simplesmente pegar cada pixel na imagem de origem e movê-lo diretamente para sua nova localização na imagem de destino. Na verdade, é mais ou menos isso o que realmente acontece nas Distorções Simples, no Recorte de Imagem e até na distorção de Imagens Vetoriais. Cada pixel (ou coordenada) é simplesmente movido para sua nova posição na imagem final. Infelizmente, isso apresenta problemas quando se tenta fazê-lo para qualquer coisa além de uma distorção simples. Por exemplo, aqui pego uma lista de Pixels Enumerados de uma imagem pequena e simplesmente altero a localização de cada pixel, de modo a rotacioná-la para sua nova posição. |

  # Rotate by 17 degrees -- get the Sine and Cosine of this angle
  sin=`magick xc: -format "%[fx:sin( 17 *pi/180)]" info:`
  cos=`magick xc: -format "%[fx:cos( 17 *pi/180)]" info:`

  # For each Pixel, rotate that pixels coordinates
  magick koala.gif  txt:- |  sed '2,$ s/,/:/' |\
    gawk -F: 'NR == 1 { print }
              NR > 1 {  x = $1-32;    y = $2-32;
                        nx = int( c*x - s*y + 32 );
                        ny = int( s*x + c*y + 32 );
                        printf( "%d,%d: %s\n", nx, ny, $3 );
              }' s=$sin c=$cos - |\
      magick -background black  txt:-   koala_rotated_direct.gif

[IM Output]
A distorção é uma rotação simples de apenas 17 graus, mas os resultados não são nada bons. Em primeiro lugar, cada nova localização de pixel é um valor de ponto flutuante, mas os pixels só podem existir em uma grade de inteiros, então o exemplo acima simplesmente descarta a fração não inteira dos resultados. O segundo problema é que o resultado está cheio de buracos onde nenhum pixel foi parar. O que traz o terceiro problema. Talvez não se perceba, mas para cada buraco na imagem resultante também se encontraria outra localização onde dois pixels foram colocados. Ou seja, há múltiplos pixels na mesma localização. Qual valor de pixel deve ser usado? No exemplo acima, o IM simplesmente usou o último pixel definido para uma localização. Em outras palavras, a imagem resultante é incompleta, em que cada pixel no destino não está exatamente onde deveria estar, e poderia ter múltiplos pixels, ou nenhum pixel. Esses são problemas sérios, e um deles não pode ser resolvido facilmente ao mapear pixels diretamente da imagem de origem para a imagem de destino (mapeamento direto). Isso não quer dizer que não possa funcionar, e muitos artigos de pesquisa falam sobre o uso de uma técnica conhecida como 'splatting '. Basicamente, pega-se cada pixel de entrada, transforma-se sua localização e então desenha-se com espalhamento e mistura apropriados das cores dos pixels na nova localização. Essa técnica é especialmente útil ao lidar com a digitalização 3D de objetos do mundo real. Aqui se tem uma 'nuvem' de pontos de superfície com cor conhecida. Qualquer ponto visível ao usuário é simplesmente 'splatado' na tela de modo a formar uma imagem final. Com pontos suficientes, a imagem parecerá completa. Com controles 3D interativos, funciona muito bem e é muito rápido. Fazer splatting de pontos tridimensionais, no entanto, está além do escopo do IM de manipular imagens rasterizadas 2D.

Mapeamento Reverso de Pixels

Em vez de tentar mapear pixels para dentro da imagem final, é possível mapear a coordenada de cada pixel na imagem de destino para a localização correspondente na imagem de origem e, a partir da imagem de origem, consultar a cor que aquele pixel deveria conter. Isso é conhecido como Mapeamento Reverso de Pixels e é o que praticamente todo programa de distorção de imagens faz. Como cada pixel da imagem de destino é processado, podemos ter certeza de que cada pixel no destino recebe uma e apenas uma cor. Assim, desde que consigamos descobrir a localização de 'origem' para cada pixel de destino, podemos distorcer uma imagem de origem para a imagem de destino usando qualquer fórmula matemática imaginável.

[Diagram]

Em resumo, um mapeamento de distorção (mapeamento reverso) faz o seguinte.

For each pixel (I,J) in the destination or output image
   Map the I,J pixel position to a X,Y pixel position in the original image
   Look up the Color of the original image at position X,Y
       Using color interpolation, work out the appropriate color.
       Or the virtual-pixel setting, if it misses the actual source image.
   Set the destination images color for pixel I,J

Note que usei os nomes de variáveis 'I,J' e 'X,Y' acima, pois essas variáveis correspondem aos nomes de variáveis que normalmente se usaria no Operador FX DIY. Por exemplo, aqui simulo a mesma rotação de 17 graus que tentei antes, mas desta vez uso o operador "[-fx](https://imagemagick.org/command-line-options/#fx)" para consultar o pixel mais próximo daquela localização na imagem de origem. |

  # Rotate by 17 degrees -- get the Sine and Cosine of this angle
  sin=`magick xc: -format "%[fx:sin( 17 *pi/180)]" info:`
  cos=`magick xc: -format "%[fx:cos( 17 *pi/180)]" info:`
  cx=37; cy=37;   # center of rotation

  magick -size 75x75 xc:       koala.gif  \
          -virtual-pixel Black  -interpolate NearestNeighbor \
          -fx "ii = i - $cx;   jj = j - $cy;
               xx =  $cos*ii +$sin*jj + $cx;
               yy = -$sin*ii +$cos*jj + $cy;
               v.p{xx,yy}" \
          koala_rotated_fx.gif

[IM Output]
É possível obter mais detalhes sobre o exemplo DIY acima na subseção sobre Mapeamento de Distorção Afim DIY. Como se pode ver, não temos mais 'buracos' em nossa imagem, pois uma cor é consultada para cada pixel no destino. Ainda não parece muito bom, mas isso é uma questão de ajustar exatamente qual cor deve ser colocada em cada pixel. Ou seja, o Mapeamento Reverso de Pixels não gera nem buracos nem pixels sobrepostos. Cada pixel tem uma cor devidamente definida, produzindo uma imagem completa.
A distinção entre mapeamento direto e reverso é importante, pois a maioria das transformações matemáticas é definida como mapeamentos diretos, mapeando uma única posição de origem (X,Y) para uma posição de destino (I,J). E, de fato, um 'mapeamento direto' funciona bem para gráficos vetoriais e para desenhar linhas, onde basta mapear as extremidades da linha e desenhá-la. Isso é especialmente verdadeiro para qualquer transformação linear, como rotações, em que as linhas permanecem retas. É, na verdade, o que se faz em todas as linguagens baseadas em vetores, como postscript e SVG. Mas para uma imagem rasterizada geral, é preciso usar um 'mapeamento reverso' para distorcer a imagem, de modo a garantir o 'preenchimento' de todos os pixels da imagem de destino. Por exemplo, se você observar a matemática usada para mapear as coordenadas nos dois casos acima, verá que elas parecem quase exatamente iguais. O mapeamento reverso de uma 'rotação' é outra 'rotação', apenas na direção oposta. Se olhar de perto, verá que a constante 'sin' está negada em relação à versão de mapeamento direto, e isso basta para reverter a direção da rotação. Esse detalhe é importante e crítico. O problema é que nem todas as transformações de mapeamento direto funcionam bem como uma transformação revertida. Alguns mapeamentos diretos, na verdade, não têm mapeamentos reversos diretos simples. Isso não quer dizer que não possam ser feitos, apenas não de forma simples. Por outro lado, algumas transformações de imagem funcionam muito bem como mapeamento reverso, mas não têm mapeamentos diretos simples. Portanto, usar o método de mapeamento reverso é bom e ruim em termos matemáticos.
A título de informação, aqui está o equivalente mais rápido ao acima, usando um método de Distorção Geral, SRT que faz exatamente a mesma rotação da imagem feita acima, produzindo exatamente o mesmo resultado, apenas mais rápido. Novamente, a consulta de cor fica restrita apenas à cor do pixel mais próximo da posição mapeada, usando a interpolação 'point'. Isso significa que nenhuma cor nova é adicionada à imagem (a não ser quando 'erramos' a imagem de origem), mas também se obtêm efeitos severos de aliasing. |

  magick koala.gif  -virtual-pixel Black  -interpolate NearestNeighbor \
          -filter point    -distort SRT 17    koala_rotated_srt.gif

[IM Output]
| Para uma discussão alternativa sobre transformações de distorção, vejaLeptonica, Affine Implementation e, especificamente, sua discussão sobre o método 'point-wise'. O outro método, 'sequential', é essencialmente como o IM costumava implementar seus operadores de distorção Rotate e Shear.
---|---
O que há em um nome? Durante meu estudo, descobri que não há uma nomenclatura realmente clara para esse método de processamento de imagens. O processo algorítmico em si é conhecido como 'Reverse Pixel Mapping ' (Mapeamento Reverso de Pixels), enquanto o uso de equações matemáticas é conhecido como 'Geometric Transformation ' (Transformação Geométrica). Se a distorção é controlada pelo movimento de vários pontos de controle, é frequentemente conhecida como 'Image Warping ' ou 'Rubber Sheeting '. O processo de definir pontos específicos, geralmente para encontrar pontos equivalentes entre duas ou mais imagens, é conhecido como 'Image Registration '. As imagens também podem ser subdivididas em unidades menores e mais simples que são distorcidas individualmente usando uma técnica chamada 'Gridding ' (quadriláteros) e 'Triangular Meshing ' (triângulos). Usando pequenas distorções incrementais com mesclagem das cores de duas imagens, é possível gerar 'Image Morphs ' animados, como os que se veem em filmes e clipes musicais. Se uma imagem de mapeamento pré-preparada é usada em vez de uma consulta matemática em tempo real, obtém-se 'Absolute Distortion Mapping '; se a consulta é um deslocamento relativo (cinza 50% significando nenhum deslocamento ou alteração da coordenada de consulta), obtém-se 'Displacement Mapping '. Se o mapeamento apenas modifica ligeiramente a cor (sombreamento) em vez de distorções de consulta, obtém-se o relacionado, mas diferente, 'Bump Surface Mapping '. Na modelagem 3D e em jogos de computador 3D, as mesmas técnicas também são usadas para dar algum tipo de padrão colorido a superfícies planas e curvas em um método conhecido como 'Texture Mapping '. Isso pode envolver a subdivisão de imagens em grades e malhas que se aproximam de um único pixel. Então tem-se a visualização de um objeto que é definido em termos de milhões de pontos individuais usando uma técnica chamada 'Point Splatting ', embora ela seja tipicamente aplicada usando uma distorção de mapeamento direto. Todos os itens acima são muito intimamente relacionados e, no fundo, envolvem a consulta da cor de um pixel com base no mapeamento de uma coordenada final de destino para a imagem (ou objeto) de origem. Em outras palavras, mapeando Destino para Origem. Qual termo deve ser usado... Escolha o seu.

Consulta de Cor de Pixel

Ainda há alguns problemas com a técnica de Mapeamento Reverso de Pixels acima. O primeiro é que, ao mapear um pixel de uma posição inteira fixa no destino, pode-se acabar com uma posição não inteira na imagem de origem. Ou seja, uma localização que cai em algum ponto entre os pixels individuais da imagem de origem. Para determinar qual cor deve ser retornada, um processo chamado Interpolação é usado para determinar a cor final para aquela posição real, misturando as cores dos pixels vizinhos. A configuração de Interpolação também tratará o caso em que uma parte de uma imagem distorcida fica 'esticada', de modo que um único pixel de origem se espalha por uma grande área da imagem de destino. No entanto, o caso oposto não é tratado muito bem por um método de interpolação simples. E isso requer outras técnicas que veremos abaixo. Por exemplo, aqui rotacionamos novamente nosso coala, mas desta vez usamos a configuração "[-interpolate](https://imagemagick.org/command-line-options/#interpolate) [Mesh](misc.html#mesh)" para misturar os quatro pixels próximos e, assim, produzir uma cor melhor e mais correta a partir da consulta. |

  magick koala.gif  -virtual-pixel Black  -interpolate Mesh \
          -filter point    -distort SRT 17    koala_rotated_mesh.gif

[IM Output]
Como se pode ver, usando uma simples mesclagem apenas das cores vizinhas mais próximas ao redor do ponto de consulta não inteiro, é possível melhorar muito a aparência da imagem distorcida. Mas há outros problemas envolvidos... Por exemplo, o que fazer quando a posição mapeada 'erra' completamente a imagem de origem. Nesse caso, qual cor deve ser retornada é determinado pela configuração de Pixel Virtual. Essa configuração escolherá uma cor, como a borda mais próxima da imagem de origem, fingirá que a imagem de origem é ladrilhada infinitamente (ou ladrilhada em espelho) pelo plano, ou usará alguma cor específica como 'white', 'black' ou 'transparent', ou a cor de fundo definida pelo usuário. Há também a possibilidade de não existir coordenada matematicamente válida para uma posição de destino específica sendo mapeada. Por exemplo, o pixel olha para o 'céu' de um 'plano' em perspectiva (Veja Vendo Horizontes Distantes) e, portanto, nem sequer vê o 'plano' em que a imagem de origem se encontra. Nesse caso, um Pixel Virtual é inútil, pois ele 'atinge' o plano da imagem de origem em um espaço N-dimensional e, como tal, o pixel de destino é completamente inválido! Nesse caso, o IM usa a configuração "[-alpha set](https://imagemagick.org/command-line-options/#alpha)" atual para a cor do pixel. Se for um 'quase-erro', o IM fará antialiasing dessa cor inválida com as cores vizinhas do plano da imagem, se souber como. E ele sabe, para distorções em perspectiva.

Superamostragem

A interpolação funciona bem para distorções simples de imagem. Mas se parte da imagem de origem for comprimida em uma área muito menor, cada pixel de destino poderia, na verdade, exigir a mesclagem de uma área muito maior da imagem de origem. Lembre-se de que os pixels não são realmente pontos, mas representam uma área retangular de uma imagem real. Isso significa que, em alguns casos, deveríamos realmente estar tentando comprimir uma grande área da imagem de origem em um único pixel de destino. Quando isso acontece, uma simples Consulta de Pixel falhará, pois ela consulta apenas a cor em um único 'ponto' na imagem de origem (usando a vizinhança de pixels ao redor) e não mescla nem combina todas as cores da imagem de entrada que talvez precisem ser comprimidas naquele único pixel. O resultado disso é que um pixel de destino poderia acabar com uma cor essencialmente aleatória da imagem de origem, em vez de uma média de todas as cores envolvidas. Isso não é ruim em si, mas quando todos os pixels de uma área fazem isso, obtêm-se imagens com pixels aparentemente aleatórios e isolados, efeitos de Moiré e efeitos de 'escada' com aliasing. Linhas finas também começam a parecer mais linhas pontilhadas e tracejadas (veja os exemplos do Operador Sample) ou podem desaparecer por completo. Todos esses efeitos são conhecidos coletivamente como Artefatos de Aliasing. Uma solução para isso é fazer mais consultas de cor na imagem de origem, para cada pixel no destino, de modo a tentar determinar uma cor mais correta para cada pixel na imagem de destino. A solução mais simples é geralmente conhecida como superamostragem ou sobreamostragem. Veja a Entrada da Wikipédia sobre Super-Sampling. Ao coletar mais amostras da imagem de origem, sobre a área que será mapeada em cada pixel de destino, a cor final daquele pixel se tornará uma representação mais precisa da imagem distorcida naquele ponto. Quanto mais amostras de cor forem feitas, mais precisa será a cor final, e uma aparência mais suave e realista será gerada, embora a distorção fique mais lenta. Lembre-se de que essa técnica só melhora realmente a aparência geral do destino em áreas onde a imagem de origem é comprimida em mais de 50%. Em áreas onde a distorção amplia a imagem de origem, ou a mantém aproximadamente na mesma escala, uma única Consulta Interpolada da imagem de origem geralmente produzirá um bom resultado com apenas uma consulta. Nos exemplos de deformação de Imagens Implodindo (e em muitos outros exemplos ao longo dos IM Examples), abordei brevemente o método mais simples de 'superamostragem'. Basicamente, ampliar o tamanho da imagem de saída (ou, neste caso, simplesmente ampliar a imagem de entrada) e então realizar a distorção. Depois que a distorção estiver completa, redimensionamos a imagem de volta ao seu tamanho normal, o que mescla todas as 'amostras' extras que foram geradas. Por exemplo...

  magick -size 94x94 xc:red -bordercolor white -border 3 \
          -virtual-pixel tile                -implode 4 \
          implode_tiled_box.gif
  magick -size 94x94 xc:red -bordercolor white -border 3 \
          -virtual-pixel tile  -resize 400%  -implode 4 -resize 25% \
          implode_tiled_ss.gif

[IM Output]
Implosão Normal de uma Imagem de Caixa | [IM Output]
Implosão com Superamostragem
---|---

É claro que, em vez de ampliar a imagem de entrada, você poderia começar com uma imagem de origem de maior qualidade (maior) ou gerar uma durante alguma etapa de processamento anterior. Se houver uma disponível. Isso é especialmente útil ao rotacionar texto, que muitas vezes tem detalhes muito finos que precisam ser preservados uniformemente para garantir uma boa aparência de alta qualidade na imagem final. Para exemplos disso, veja a Transformação Polaroid. A partir do IM v6.4.2-6, oOperador de Distorção Geral pode gerar diretamente uma imagem de saída ampliada, que você pode reduzir (ou redimensionar) para mesclar e superamostrar os pixels resultantes. Veja Configuração de Escala de Distorção, bem como o próximo exemplo.
Este é apenas um método de superamostragem (conhecido como método de 'grade'); há, no entanto, muitas outras variações desse método. Eventualmente, esses métodos poderão ser implementados de forma mais direta no ImageMagick, mas por ora a simples ampliação e o escalonamento de imagens funcionam bastante bem, sem necessidade de código adicional. Uma última palavra de advertência. A superamostragem é limitada pelo número de amostras usadas para cada pixel na imagem final e, portanto, pela quantidade de escalonamento usada no redimensionamento final. Isso determina a 'qualidade' final da imagem distorcida. Mas ao usar fatores de escalonamento maiores, a imagem distorcida será, claro, muito mais lenta de gerar. Ter qualidade ainda maior tem seus limites. No extremo, a superamostragem não lidará com nenhuma distorção de imagem que envolva infinitos (como no centro de uma imagem implodida). Nesses casos, é necessária uma técnica completamente diferente, como a fornecida pela Reamostragem de Área (veja abaixo). Em resumo, a superamostragem pode melhorar a aparência de imagens com apenas pequenas distorções, como rotações, cisalhamentos, afim e perspectiva simples. Mas ela tem limites quanto aos tipos de distorções que pode melhorar. Superamostragem Adaptativa A técnica de superamostragem pode ser expandida ainda mais. Em vez de simplesmente usar um número fixo de consultas de cor para cada pixel, faz-se uma verificação seja da distância entre as consultas na imagem de origem, seja de quão próximas estão as cores retornadas de uma amostragem de baixo nível, para ver se deve fazer mais amostras para aquele pixel específico. Ou seja, a quantidade de superamostragem poderia ser feita responsiva às necessidades da distorção, sem saber nada sobre as especificidades da própria distorção. Isso é conhecido como Superamostragem Adaptativa. Essa técnica é, na verdade, muito comum em Ray Tracers, onde é quase impossível determinar o quão complexa é a imagem resultante em qualquer ponto específico. Nesse caso, ela é frequentemente restrita ao uso de 'diferenças de cor' ao redor da localização específica, para determinar quando mais amostras são necessárias. Se um pixel é muito diferente de seus vizinhos, então mais amostras são usadas nessa área para refinar o que provavelmente é a borda de algum objeto tridimensional. O IM não oferece suporte a superamostragem adaptativa no momento. Embora seja bastante possível adicionar métodos de amostragem alternativos ao Operador de Distorção Geral (veja abaixo). Isso exigirá algum rearranjo funcional do código, então pode não ser adicionado tão cedo. Resumo da Superamostragem A dificuldade com a superamostragem está em determinar exatamente quantas 'amostras pontuais' são necessárias e como essas amostras devem ser dispostas dentro dos limites de subpixel. Também que tipo de 'ponderação' deve ser aplicada. Veja a Entrada da Wikipédia sobre Super-Sampling.

Reamostragem de Área, para melhores Distorções

Uma das melhores alternativas aos métodos de superamostragem é a Reamostragem de Área. Em vez de distorcer uma imagem maior e fazer a média dos resultados por meio do redimensionamento, o que é apenas coletar e fazer a média de mais amostras da imagem, na verdade determinamos exatamente quantos pixels da imagem de origem devem ser mesclados (com base na 'escala' da distorção naquele ponto) para gerar cada pixel de saída específico. Ou seja, descobrir uma 'área' aproximada dentro da imagem de origem que cada pixel de saída representa e mesclar (filtrar) todos os pixels dessa área de acordo com um filtro de reamostragem. Na verdade, isso é exatamente o que o Operador Resize do ImageMagick (na realidade um tipo muito específico de distorção de imagem) faz para gerar resultados tão bons. No entanto, para o resize, você só precisa calcular a escala da área que precisa ser amostrada para cada pixel uma vez para toda a imagem. A área que ele precisa 'amostrar' é um retângulo (janela) de tamanho fixo na imagem de origem, o que torna o processo de reamostragem fácil e fornece um atalho no processo de distorção. Ao reamostrar por área uma imagem distorcida, a área de pixel (janela) da qual obter amostras não apenas mudará de posição, mas também mudará de tamanho. Assim, um pixel no destino pode precisar mesclar apenas algumas cores da imagem de origem, ou mesmo apenas uma única consulta de cor interpolada (como em ampliações). Enquanto outro pixel em outra parte da imagem de destino pode precisar amostrar um número muito, muito grande de pixels para gerar a cor final correta. Perto de infinitos, ele pode até ter de incluir todos os pixels da imagem de origem como parte do processo de amostragem. Além disso, a área que um pixel de destino representa na imagem de origem pode não ser um simples quadrado, círculo ou mesmo elipse, mas pode, na verdade, ser uma forma altamente distorcida, de acordo com a distorção sendo usada. Calcular e lidar com essas formas complicadas pode consumir muito tempo, ou ser quase impossível de conseguir. [Diagram] Usar uma área elíptica da imagem de origem para calcular as cores de cada pixel de destino é um método conhecido como Reamostragem por Média Ponderada Elíptica (EWA), e foi descrito no artigo de pesquisa em PDF "Fundamentals of Texture Mapping and Image Warping" por Paul Heckbert (que também escreveu o programa 'zoom', do qual praticamente todos os algoritmos de redimensionamento de imagem derivam). Isso foi então usado para definir o novo Operador de Distorção Generalizado (veja abaixo). Uma elipse é a forma perfeita tanto para Distorções Afins quanto para Distorções em Perspectiva. É especialmente boa para reduções extremas de escala (veja o exemplo abaixo). E, embora não seja perfeita para outras distorções, geralmente é um ajuste razoável para muitas outras distorções, como Distorções em Arco e Polares (mas não suas reversas), bem como distorções radiais como a Distorção Barril. Mas é um ajuste ruim para mapeamentos de distorção não lineares, como De-Polar e Distorção de Shepards; por isso, ela não é usada para essas distorções. A Superamostragem não tem esse problema de forma, pois cada 'amostra' é mapeada de forma reversa sobre o destino. Assim, ela se torna o melhor método de amostragem nesses casos. Mas, como mencionado, ela pode não amostrar todos os pixels necessários, ou mesmo amostrar pixels demais.

Amostragem de Área vs Superamostragem

Aqui estão todos os três métodos de amostragem que o IM atualmente fornece, quando aplicados a uma imagem em perspectiva ladrilhada infinitamente e extrema. Veja Vendo Horizontes Distantes abaixo para detalhes dessa distorção.

  # input image:  special checkerboard with a gold outline.
  magick -size 90x90 pattern:checkerboard -normalize -fill none \
          -stroke gold -strokewidth 3 -draw 'rectangle 0,0 89,89' \
          -fill red        -draw 'color 20,20 floodfill' \
          -fill lime       -draw 'color 40,70 floodfill' \
          -fill dodgerblue -draw 'color 70,40 floodfill' \
          checks.png

  # Using Interpolated Lookup
  magick checks.png -filter point \
          -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_tile_point.png

  # Using Grid Super Sampling
  magick checks.png  -filter point  -set option:distort:scale 10 \
          -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          -scale 10%    horizon_tile_super.png

  # Using Area Resampling (default)
  magick checks.png       -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_tile.png

[IM Output]
Imagem Xadrez | | [IM Output]
Interpolada
Consulta | [IM Output]
Superamostragem
x10 | [IM Output]
Área Ponderada Elíptica
(EWA) Reamostragem
---|---|---|---|---

Todas as imagens têm exatamente a mesma distorção, apenas usando diferentes técnicas de 'reamostragem'. A última imagem acima usou as configurações EWA padrão do Operador de Distorção Generalizado e, como se pode ver, produziu um resultado de qualidade extremamente alta. No entanto, levou 4,6 segundos para gerar essa imagem, o que não é ruim, ainda que um pouco lento (devido aos extremos incomuns envolvidos). A primeira imagem tem a reamostragem EWA padrão desativada usando a configuração "[-filter](https://imagemagick.org/command-line-options/#filter) point". Isso a força a usar a Consulta Interpolada Direta para cada pixel. Assim, essa imagem foi gerada de forma extremamente rápida em comparação (0,51 segundos), mas, como se pode ver, produz um resultado horrível à medida que a 'minificação' (subamostragem) aumenta com a 'distância'. A imagem do meio é como a primeira imagem, mas com a imagem de saída distorcida sendo ampliada por um fator de 10, antes de ser reduzida de volta (reamostragem em grade) para corresponder às outras imagens. Ou seja, mais de 100 pixels foram consultados e sua média foi calculada para cada pixel de destino, de modo a Superamostrar o resultado. É bastante rápida de gerar (1,2 segundos) e, embora melhore a qualidade da imagem em geral, essa melhoria é limitada. O ×10 usado no exemplo acima é muito pesado, excedendo em muito o escalonamento mais típico de 3 ou 4 vezes usado na maioria dos usos de superamostragem. A maior diferença entre os resultados é que a superamostragem só faz uma melhoria geral de qualidade uniformemente sobre toda a imagem. À medida que a distorção fica mais severa, ela começa a se degradar. O resultado são os Artefatos de Reamostragem altamente visíveis no plano intermediário e, mais especificamente, uma linha de efeitos severos de moiré logo antes do horizonte. O efeito moiré é causado quando as 10 amostras por pixel quase coincidem com o padrão de tabuleiro de xadrez da imagem, produzindo efeitos de cor distorcidos. Por outro lado, a reamostragem de área concentra-se mais nos pixels problemáticos próximos ao horizonte (onde gasta quase todo o seu tempo) do que nos pixels em primeiro plano, onde de fato supera a superamostragem. Basicamente, o exemplo acima é uma distorção muito extrema, e o tempo que a consulta EWA leva é proporcional. Mais comumente, ela gera resultados muito melhores do que uma única consulta interpolada, pois examina eficientemente cada pixel envolvido, sem usar amostras demais em áreas que não precisam, como faz a superamostragem. Em Resumo... Usar uma simples elipse (reamostragem EWA) ou um retângulo (Resize) para fazer a 'reamostragem de área' de fato produz bons resultados, pois todos os pixels de origem envolvidos em distorções escaladas, afins ou em perspectiva serão mesclados para produzir a cor final de um pixel de destino individual. Em casos de distorções muito não lineares, como em Distorções DePolar, ou distorções indeterminadas, como a Distorção de Shepard ou mesmo ray-tracing, encontrar a 'Área' correta para reamostrar todos os pixels de origem necessários torna-se proibitivo, e a superamostragem é o melhor método para melhorar os resultados. Mas para ladrilhamento simples, ampliações e rotações sem escala, uma única consulta interpolada 'point' muito rápida é provavelmente tudo o que é necessário, e pode até ser recomendada para garantir distorções perfeitas sem efeito (sem alteração) (veja abaixo). Lembre-se, no entanto, de que todas as técnicas de reamostragem são apenas métodos para determinar a cor de cada pixel individual. Não fazem parte, na verdade, de como uma imagem é distorcida, exceto no que diz respeito ao mapeamento de localizações entre destino e origem (ou vice-versa, se possível).


Operador Generalizado de Distorção

Com a geração desses exemplos, as discussões subsequentes nos Fóruns do IM e diversos pedidos de usuários por formas mais fáceis e rápidas de fazer perspectiva e outras distorções, um novo operador foi adicionado ao IM v6.3.5-1 para permitir adicionar mais facilmente distorções de imagem, de muitos tipos diferentes. Esse Operador Generalizado de Distorção chama-se "[-distort](https://imagemagick.org/command-line-options/#distort)", e é possível ver quais métodos de distorção estão disponíveis na sua versão do IM usando "[-list](https://imagemagick.org/command-line-options/#list) Distort".

  magick -list distort

O operador "[-distort](https://imagemagick.org/command-line-options/#distort)" recebe dois argumentos, um dos métodos de distorção conforme dado acima, e um segundo argumento em string composto por uma lista de valores de ponto flutuante separados por vírgula ou espaço, usado para controlar o método de distorção específico.

  magick ... -distort  {_method_}  "{_list_of_floating_point_values_}" ...

A quantidade de valores de ponto flutuante fornecidos, contudo, depende fortemente do método de distorção em uso, e seus significados dependem não apenas do method escolhido, mas também podem depender do número exato de pontos de controle ou atributos necessários para um método específico. Esse é especialmente o caso da distorção '[Scale-Rotate-Translate](#srt)' (ou '[SRT](#srt)' de forma abreviada), que na verdade combina três distorções '[Affine](#affine)' separadas em uma única distorção. Muitos métodos de distorção recebem uma lista de pontos de controle (em Coordenadas de Imagem), e normalmente estes são dados como pares de coordenadas que controlam como a distorção deve modificar a imagem. Esses pares de coordenadas são detalhados mais completamente adiante em Distorções Usando Pontos de Controle.

Opções, Controles e Configurações de Distorção

Flag de Melhor Ajuste +Distort

Por padrão, "[-distort](https://imagemagick.org/command-line-options/#distort)" geralmente distorce a(s) imagem(ns) de origem em uma imagem do mesmo tamanho da imagem original. Há exceções a isso, como a distorção '[Arc](#arc)' (uma variante de mapeamento polar) em que o tamanho da imagem de origem realmente não tem muito significado na forma distorcida da imagem (veja Distorção Arc abaixo para detalhes). A outra forma do operador, "[+distort](https://imagemagick.org/command-line-options/#distort)" (adicionada ao IM v6.3.5-7), tentará redimensionar a imagem distorcida para que contenha toda a imagem de entrada (se possível), de forma parecida ao que os operadores mais antigos de Rotação e Cisalhamento fazem. No entanto, esse 'modo' de operação em particular vai além e também define o Deslocamento da Tela Virtual (page) da imagem resultante. Dessa forma, é possível depois fazer Fusão de Camadas dessa imagem sobre outra imagem, na posição correta de acordo com seus pontos de controle, usando a Composição Alfa apropriada (veja Cubos 3d, usando Camadas Afins como um exemplo básico. Além disso (dependendo do método de distorção), um "[+distort](https://imagemagick.org/command-line-options/#distort)" tentará levar em conta qualquer Deslocamento da Tela Virtual existente que possa estar presente na imagem de origem, e usá-lo como parte do processo de distorção. Veja as notas sobre os métodos de distorção individuais. Assim, pode ser necessário usar com prudência o operador de configuração de atributo "[+repage](https://imagemagick.org/command-line-options/#repage)" para limpar ou ajustar esse deslocamento antes de usar a forma de 'melhor ajuste' "[+distort](https://imagemagick.org/command-line-options/#distort)" do Operador Generalizado de Distorção. Também pode ser necessário usá-lo depois caso a tela virtual e o deslocamento não sejam necessários. Veja também Removendo Geometria de Tela/Página. O "[-distort](https://imagemagick.org/command-line-options/#distort)" normal simplesmente ignorará qualquer deslocamento existente presente na imagem de origem em termos da distorção em si, mas copiará esse deslocamento inalterado para a imagem distorcida. Em Resumo... Use "[-distort](https://imagemagick.org/command-line-options/#distort)" para ter os resultados mapeados em uma imagem do mesmo tamanho. E use "[+distort](https://imagemagick.org/command-line-options/#distort)" para tentar definir automaticamente o tamanho da imagem de saída, MAS também usar e gerar Deslocamentos de Tela Virtual (atributos de page). Veja também Viewport de Distorção (abaixo) se quiser sobrescrever essa seleção geral de viewport, e controlar exatamente qual tamanho e qual parte da imagem distorcida deseja ver nos seus resultados.
Nota... O viewport de melhor ajuste gerado por "[+distort](https://imagemagick.org/command-line-options/#distort)" é 2 pixels maior do que os usuários normalmente esperariam. A razão é que esses pixels contêm pixels semitransparentes resultantes do filtro de reamostragem por área, e esses pixels são vitais para a correta 'junção de bordas' e sobreposição da imagem distorcida. Tecnicamente, o número de pixels adicionados deveria depender da escala de saída do Suporte do Filtro de Reamostragem. Ou seja, quanto a área de um pixel poderia 'espalhar' devido ao filtro de reamostragem. Contudo, como a escala de cada pixel pode ser variável, o cálculo do número absolutamente correto de pixels adicionais necessários é uma questão muito complicada, e normalmente não vale o esforço. Os 2 pixels adicionados são, portanto, um 'improviso', já que distorções raramente ampliam imagens, o que faz os pixels 'espalharem' mais. Além disso, como a maioria dos filtros de reamostragem padrão tem um suporte de 2 unidades, a adição de 2 pixels é razoável. E, como essa adição é 'fixa', permite aos usuários a opção de simplesmente Recortar o Tamanho da Imagem (de várias formas), se assim desejarem. O 'improviso' de 2 pixels torna-se obviamente pequeno demais ao fazer ampliações de imagens. Mas essas são distorções bastante raras, e os usuários podem definir seu próprio Viewport (veja abaixo) se isso for um problema. O deslocamento virtual da imagem distorcida na tela virtual é ajustado para levar em conta esses 2 pixels extras, de modo que a imagem distorcida fica correta para sobreposição, embora não para composição simples. Mas fique avisado que, enquanto Crop e Trim preservarão a localização da imagem em camada, Shave e Chop deslocarão a imagem da camada, em relação a esse deslocamento.

Determinação da Cor do Pixel na Distorção

Como discutido acima em Mapeamento Reverso de Pixels, cada ponto na imagem resultante é determinado primeiro mapeando a localização daquele pixel na imagem de destino para a localização equivalente (distorcida ao reverso) na imagem de origem, de acordo com o método de distorção escolhido. No entanto, a cor final do pixel não é tão simples de determinar, já que é afetada por um grande número de fatores.

Pixels Virtuais e Ladrilhamento

O ponto mapeado pela distorção pode não atingir a imagem de origem real, mas algum lugar ao lado dela, ou até muito distante da imagem real. A solução para isso é fingir que a imagem de origem está cercada por uma superfície 'infinita' ou 'virtual', que é definida pela configuração "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" atual. Para detalhes e exemplos do efeito dessa configuração, veja os exemplos de Pixel Virtual. Isso pode ser muito útil para gerar padrões de ladrilho, distorcidos ou mesmo não distorcidos, da imagem de origem. Técnicas para isso são mostradas na própria seção Pixel Virtual (não distorcido) e em Ladrilhamento Afim e Ver Horizontes Distantes abaixo.

Pixels Inválidos de Distorção

Às vezes, a distorção de um pixel de destino nem sequer 'atinge' a imagem ladrilhada virtual! Isso geralmente acontece quando se distorce a imagem usando algum tipo de método de distorção em espaço tridimensional e o 'vetor' do pixel nem sequer atinge o plano de origem no qual a imagem está. Basicamente, o resultado da distorção torna-se 'indefinido' matematicamente. Nesse caso, a cor será determinada a partir da configuração "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)". Por exemplo, quando se vê 'céu' em uma Distorção de Perspectiva (por exemplo, veja Ver Horizontes Distantes), a matemática para determinar a localização na imagem de origem tornou-se 'indefinida' (na verdade ela é definida, mas não é válida a partir da perspectiva de visualização direta do usuário). Assim, o "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" é gerado para o 'céu'. Na verdade, o algoritmo de distorção de perspectiva também consegue incluir alguma informação de 'anti-aliasing' para pixels próximos ao horizonte, embora isso seja incomum para tais situações.

Reamostragem EWA e Filtros

Uma vez que se sabe onde um pixel de destino 'atinge' a imagem de origem, é preciso determinar a cor a atribuir ao pixel de destino, usando os pixels próximos ao ponto de 'impacto' na imagem de origem. Normalmente, o Operador de Distorção usará o método de Reamostragem por Área EWA (Elliptical Weighted Average) para calcular a média de uma área maior da imagem de origem e determinar a cor correta para esse pixel. É possível mudar o filtro usado pela reamostragem EWA por meio da configuração "[-filter](https://imagemagick.org/command-line-options/#resize)". Veja Filtros de Reamostragem, e mais especificamente Filtros Cilíndricos para mais detalhes. Originalmente, um filtro Gaussiano Cilíndrico era usado para reamostragem EWA, já que era o que estava definido no artigo de pesquisa original sobre reamostragem EWA. Mas ele tende a produzir resultados muito borrados, embora também não produza efeitos de aliasing. Esse costumava ser o filtro padrão, junto com um bug de implementação que causava borrão extremo antes daquela versão (agora corrigido). A partir do IM v6.6.5-0, após grandes discussões com Nicolas Robidoux, Professor de Matemática na Laurentian University, o filtro padrão para distorções de imagem foi substituído pelo filtro '**Robidoux**', que é um filtro cúbico bastante 'similar ao Mitchell', projetado especificamente para reamostragem EWA. Veja Filtros Cilíndricos para informações sobre este e outros filtros cilíndricos. Note, contudo, que qualquer função de filtro Sinc com janela subjacente é substituída pela função de filtro Jinc com janela, mais circular. Assim, selecionar um filtro 'Lanczos' retornará um filtro "Jinc com janela Jinc", em vez de um filtro "Sinc com janela Sinc". Veja Filtros Cilíndricos Jinc com Janela para mais detalhes. À PARTE: funções 'Sinc' NÃO são realmente utilizáveis como função cilíndrica, pois a interação da função com distâncias radiais em uma grade faz os pesos do filtro assumirem uma forma que tende a se anular (soma de pesos zero) sempre que um número par de 'lóbulos' é usado. Isso, por sua vez, faz com que ela tente gerar cores quase infinitas quando usada com um padrão de 'hash' em xadrez ao nível do pixel. Basicamente, o EWA usa filtros de reamostragem, muito parecido com o Operador de Redimensionamento, e assim também é possível modificar os filtros usando as Opções de Filtro para Especialistas especiais. O borrão de um filtro 'Gaussian' e de filtros similares ao gaussiano, por exemplo, pode ser controlado pela Configuração de Borrão do Filtro. De forma semelhante, é possível usar a Configuração de Suporte de Lóbulos para controlar o tamanho e a força dos Filtros Jinc com Janela, como um filtro 'Lanczos'. | _Há vários métodos de distorção extrema que desligam automaticamente a reamostragem EWA e usam apenas aConsulta Interpolada mais direta.

Por exemplo, a distorção Depolar produz áreas de reamostragem em forma de arcos circulares que não se ajustam muito bem à reamostragem 'elíptica' (EWA). Outras distorções, como Shepards, tornam o cálculo dos 'fatores de escala' extremamente difícil, embora uma futura melhoria do operador de distorção possa torná-lo possível).

Uma técnica de Super Amostragem é recomendada para esses métodos de distorção para evitar a geração de graves Artefatos de Aliasing em áreas de compressão de imagem (redução de amostragem) nos resultados.

_
---|---

Falha na Reamostragem

Em algumas situações especiais, a elipse de reamostragem EWA pode falhar em realmente 'atingir' qualquer pixel real para criar uma média ponderada. Basicamente, a elipse é tão pequena, ou tão fina, que cai completamente entre cada pixel da imagem. E sem nenhuma cor de pixel, não é possível gerar uma cor para a imagem de saída naquele ponto. Essa é uma situação extrema, e geralmente é impossível de alcançar a menos que se esteja brincando com Configurações de Filtro para Especialistas. Mas no evento improvável de nenhum pixel ser atingido, ou os pesos do filtro somarem zero, a reamostragem falhará. Nesse caso, o IM recorrerá a uma simples consulta interpolada direta, exatamente como se obteria ao desligar a filtragem EWA (veja a seguir). Se quiser verificar se isso está acontecendo, é possível usar a Interpolação de Fundo especial com uma cor de fundo incomum (como 'red') para destacar quaisquer dessas falhas de reamostragem. Por exemplo, aqui eu propositalmente defini o suporte de um filtro box pequeno demais, tornando a elipse de reamostragem tão pequena. Também amplio muito a imagem para que se possa ver quais partes 'atingiram um pixel' e quais não. |

  magick \( xc:red   xc:white xc:black +append \) \
          \( xc:blue  xc:lime  xc:white +append \) \
          \( xc:black xc:red   xc:blue  +append \) -append \
          -filter Box -define filter:support=0.4 \
          +distort SRT 30,0  bad_box_distort.png

[IM Output]
Na imagem muito ampliada, o círculo de reamostragem ou atingirá apenas um pixel (produzindo um círculo com aliasing de cor sólida). Ou falhará em corresponder a qualquer pixel, pois a área de amostragem circular cai completamente entre os pixels, e assim o filtro recorrerá a um gradiente de cor interpolado (Interpolação Bilinear por padrão), para obter ao menos alguma cor razoavelmente válida para a imagem resultante. Aqui está o mesmo exemplo, mas substituindo o método de interpolação pela Interpolação de Fundo especial (e normalmente inútil) (que simplesmente retorna a cor de fundo, definida como 'gray'). |

  magick \( xc:red   xc:white xc:black +append \) \
          \( xc:blue  xc:lime  xc:white +append \) \
          \( xc:black xc:red   xc:blue  +append \) -append \
          -filter Box -define filter:support=0.4 \
          -interpolate background -background Gray \
          +distort SRT 30,0   bad_box_distort_gray.png

[IM Output]
Para cobertura completa (de modo que sempre encontre ao menos um pixel), um filtro de reamostragem cilíndrico precisa de um 'suporte' de pelo menos cerca de 0.707 (sqrt(2)/2) (padrão para um filtro box). Todos os filtros são tipicamente muito maiores que esse tamanho de suporte mínimo. Para exemplos disso, veja a seção sobre Filtros Cilíndricos. | _Os pequenos pontos coloridos nos cantos são causados por uma otimização de reamostragem para pixels virtuais (abortando uma reamostragem EWA custosa ao amostrar áreas de VP de cor sólida). Eles desaparecerão ou mudarão com uma seleção diferente da configuração "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)".

Normalmente isso não é um problema, e só é visto aqui porque a distorção usa um 'Viewport de Melhor Ajuste' que é ligeiramente maior que a imagem original, e assim inclui alguns pixels extras ao redor da borda que, neste caso, amostram pixel virtual.

_
---|---

Consulta de Cor Interpolada ou Direta

É possível usar "[-filter](https://imagemagick.org/command-line-options/#filter) point" para desligar a filtragem e, portanto, a reamostragem EWA.Quando isso é feito, o Imagemagick alternará as consultas de cor para usar a Interpolação de Pixel rápida e mais simples. Ou seja, buscará uma cor usando apenas uma referência de 'ponto único' à imagem de origem, sem nenhuma 'área de reamostragem'. A cor dos pixels resultantes usará uma cor interpolada baseada apenas nos vizinhos mais próximos do ponto.

A interpolação geralmente causará graves efeitos de aliasing
quando ocorre qualquer forma de minificação ou redução de amostragem da imagem.

Mas funciona extremamente bem para imagens contendo distorções mínimas, como rotações, ladrilhamento, ou para ampliação de imagem (magnificação ou aumento de amostragem). Uma técnica de Super Amostragem pode ser combinada com a interpolação, para melhorar os resultados em áreas de forte compressão, minificação ou redução de amostragem. Veja Problemas do Ciclo Depolar-Polar (uma distorção que não pode usar reamostragem EWA) para um exemplo de uso de super amostragem para resolver o aliasing interpolado.

Resumo Detalhado da Distorção

Ao definir "[-verbose](https://imagemagick.org/command-line-options/#verbose)" antes de executar "[-distort](https://imagemagick.org/command-line-options/#distort)" (use "[+verbose](https://imagemagick.org/command-line-options/#verbose)" para desligar novamente), a distorção enviará ao canal de erro padrão informações sobre o algoritmo e os coeficientes internos que calcula e usa ao distorcer a imagem dada, da maneira especificada. É possível usar essa informação para observar e entender como a distorção funciona e é aplicada. Também é uma ferramenta de depuração que pode ser usada para descobrir o que está dando errado, e como parte do processo de implementação de novas distorções.

  magick koala.gif -verbose -distort SRT 0 +verbose  koala_noop.gif

[IM Output] | | | [IM Text]

| [IM Output]

| NOTA: A imagem resultante é quase, mas não exatamente, igual à imagem de entrada (veja "distorções no-op" a seguir).
---|---
A saída verbose detalha as duas técnicas alternativas de distorção para a distorção dada. Uma é uma distorção '[AffineProjection](#affineprojection)', enquanto a outra mostra uma alternativa DIY do Operador FX detalhando exatamente como ela mapeia um pixel dado na imagem de saída (i,j) para uma consulta interpolada na imagem de entrada (xx,yy), de modo a transformar a imagem. Ela faz os cálculos da elipse de reamostragem que usam matemática complexa (autovalores) para descobrir; ela apenas calcula o ponto de consulta interpolado não escalado na imagem de origem a partir do qual determinar a cor do pixel (i,j). Ambas dão informações sobre o processo de distorção e podem ser usadas para extrair informações extras para uso em outras distorções do mesmo tipo. Para um exemplo mais complexo de uso dessa informação, veja Detalhes Internos da Perspectiva e Detalhes Internos da Bilinear abaixo. Também, para um exemplo de uso de um comando FX para distorção de imagem, veja Redimensionamento de Imagem com FX. As adições e subtrações extras de '0.5' acima são necessárias para converter 'coordenadas de pixel' em 'coordenadas de imagem', e são exigidas para o tratamento matemático correto das distorções de imagem. Veja Coordenadas de Imagem vs Pixel abaixo.

Distorções No-Op

O exemplo acima mostra os resultados de fazer uma distorção no-op. Ou seja, passar uma imagem pela distorção (para algum efeito secundário) mas sem nenhuma distorção real envolvida (apenas um mapeamento de pixels 1 para 1). O filtro de reamostragem EWA não reproduzirá exatamente as mesmas cores do original, mas borrará os pixels individuais muito ligeiramente com seus vizinhos. Isso se deve ao filtro bidimensional usado, e embora o borrão de cor seja mínimo, ele nunca pode ser eliminado. Assim, para fazer um verdadeiro 'no-op', também é preciso desligar a filtragem EWA e usar a Consulta de Cor Interpolada ou Direta (veja acima). |

  magick koala.gif -filter point -distort SRT 0  koala_noop_perfect.gif

[IM Output]
Quase todas as Configurações de Interpolação geralmente extrairão uma cópia exata do pixel de origem quando ele é referenciado exatamente. Contudo, como precaução, também é possível especificar interpolação Nearest-Neighbor, por velocidade e garantia de que apenas uma correspondência exata de cor seja retornada, independentemente de quaisquer erros de ponto flutuante que a distorção possa produzir. |

  magick koala.gif   -filter point  -interpolate nearest \
          -distort SRT 0  koala_noop_perfect_2.gif

[IM Output]
Isso pode parecer contraproducente, mas pode ser um método muito útil para ampliar a área de uma imagem, ou ladrilhar imagens (usando Métodos de Pixel Virtual), sem realmente redimensionar os dados da imagem original. Veja Ladrilhamento usando Pixels Virtuais via Distort para exemplos disso. Ou seja, usar o Operador de Distorção para seus efeitos secundários, como ladrilhamento de pixel virtual multi-imagem, ampliação ou recorte do tamanho da imagem, adição de bordas, ou mesmo translação (por quantidades inteiras ou até de sub-pixel). Nenhum dos quais realmente exige que a imagem seja 'distorcida', apenas 'modificada' de alguma forma 'programada'.

Viewport, Onde a Distorção Olha

Como mencionado acima, usar "[-distort](https://imagemagick.org/command-line-options/#distort)" ou "[+distort](https://imagemagick.org/command-line-options/#distort)" muda o tamanho e a localização resultantes da 'imagem de destino' para ser, respectivamente: igual à imagem de origem (ignorando quaisquer configurações de tela virtual), ou um cálculo de melhor ajuste para a imagem de origem distorcida (se possível). Essas duas coisas basicamente definem qual parte do 'espaço distorcido' resultante a imagem de destino está vendo. Outra forma de pensar nisso é que a imagem de destino é uma 'janela' olhando para a imagem distorcida resultante, ou um 'viewport' para o espaço distorcido. A configuração "distort:viewport" sobrescreve ambos esses padrões, e permite especificar diretamente qual parte do espaço distorcido se deseja ver...

[-define](https://imagemagick.org/command-line-options/#define) distort:viewport=WxH+X+Y
[-set](https://imagemagick.org/command-line-options/#set) option:distort:viewport WxH+X+Y

Estas foram adicionadas no IM v6.3.6-1. Não amplia nem escala a imagem distorcida, apenas especifica a localização e a área sendo vista (o viewport) no espaço da imagem distorcida. Isso pode ser usado para criar uma imagem de destino de um tamanho específico, ou deslocar a visão para uma área específica no espaço da imagem distorcida. É muito semelhante a usar 'Recorte por Viewport', de uma imagem distorcida de tamanho infinito (definida por pixel virtual). Por exemplo, aqui recortamos a saída apenas para a cabeça do coala (com uma distorção no-op). Em outras palavras, apenas um 'recorte por viewport' direto da imagem original não distorcida. |

  magick koala.gif  -define distort:viewport=44x44+15+0 \
          -filter point -distort SRT 0  +repage koala_viewport.gif

[IM Output]
E aqui expandimos a visão, para olhar o espaço extra ao redor da imagem distorcida, e mostrar os efeitos que a configuração de Pixel Virtual tem no espaço infinito ao redor da imagem de origem original. |

  magick koala.gif  -define distort:viewport=125x125-25-25 \
          -filter point -distort SRT 0  +repage koala_viewport_2.gif

[IM Output]
Nesse caso, é mais como usar o Operador Extent para ampliar a imagem. Contudo, em vez de simplesmente preencher com a cor de fundo, a distorção preenche a área adicionada com a Configuração de Pixel Virtual. Nesse caso, usando a configuração de pixel virtual '[Edge](misc.html#edge)' padrão, que resulta nas linhas horizontais e verticais de pixels, replicadas a partir dos pixels ao longo da borda da imagem original. Talvez você prefira fazer uma escolha melhor para a Configuração de Pixel Virtual. Por exemplo, usar uma configuração '[Background](misc.html#background)' fará essa distorção no-op funcionar praticamente igual ao Operador Extent. Para esta imagem, a configuração de Pixel Virtual '[White](misc.html#white)' provavelmente seria uma escolha melhor. |

  magick koala.gif  -define distort:viewport=125x125-25-25 \
          -virtual-pixel White -distort SRT 0  +repage koala_viewport_3.gif

[IM Output]
O "[+repage](https://imagemagick.org/command-line-options/#repage)" final nos exemplos anteriores é necessário para remover o deslocamento de tela virtual do viewport que "[-distort](https://imagemagick.org/command-line-options/#distort)" deixará no lugar quando a configuração de viewport for usada. Essa informação simplesmente não é desejada neste caso. Em outros casos, como ao empilhar imagens distorcidas, você desejaria essa informação de deslocamento. A opção de viewport é particularmente útil com uma configuração de pixel virtual '[Tile](misc.html#tile)' ou mesmo '[Mirror](misc.html#mirror)', permitindo gerar imagens ladrilhadas de qualquer tamanho e em diferentes estilos. É possível até usar a distorção para distorcer essas imagens ladrilhadas, como exemplificado em Ladrilhamento Afim abaixo. |

  magick koala.gif  -define distort:viewport=125x125-25-25 \
          -virtual-pixel Mirror -distort SRT 0  +repage koala_viewport_4.gif

[IM Output]

Recorte de Quadrado Centralizado

Se você usar a opção "[-set](https://imagemagick.org/command-line-options/#set)" para definir o 'viewport' da imagem resultante, pode incluir Escapes de Porcentagem no valor atribuído. Mais especificamente, é possível incluir Escapes de Porcentagem FX que podem fazer cálculos matemáticos. Isso significa que o 'viewport' pode ser calculado, fazendo uso dos atributos, digamos, do tamanho da imagem atual na memória, para especificar o tamanho final da imagem resultante. O que isso significa? Bem, significa que o 'viewport' pode ser usado para gerar tipos especiais de Recorte que normalmente exigem uma ou mais pré-leituras de uma imagem (ou uma interface de programação API mais avançada), e cálculos externos para alcançar. Por exemplo, é possível recortar um 'quadrado central' de uma imagem sem precisar conhecer o tamanho ou a orientação da imagem original de antemão. Isso é complexo, então coloquei a expressão do viewport em variáveis para torná-la mais fácil de ler, codificar e depurar, embora seja na verdade apenas uma expressão constante (fixa).

  size='%[fx: w>h ? h : w ]'
  offset_x='%[fx: w>h ? (w-h)/2 : 0 ]'
  offset_y='%[fx: w>h ? 0 : (h-w)/2 ]'
  viewport="${size}x${size}+${offset_x}+${offset_y}"

  magick worldmap_sm.jpg  -set option:distort:viewport "$viewport" \
          -filter point -distort SRT 0  +repage   viewport_square.gif

[IM Output] [IM Output]

A imagem resultante é o maior quadrado centralizado que pode ser extraído de qualquer imagem de origem de entrada, independentemente do tamanho dessa imagem. A distorção em si não distorce de fato a imagem, apenas copia a área coberta pelo viewport. Note que TODOS os quatro números precisam ser calculados para produzir um "recorte de quadrado centralizado", já que todos os valores dependem da orientação da imagem. Assim, cada expressão usa um teste de 'orientação da imagem' na forma 'w>h ? ... : ...', de modo que o valor resultante dependa da orientação da imagem. Esta é uma forma alternativa usando as funções "min()" e "max()", em vez de testes de orientação de imagem. |

  magick worldmap_sm.jpg  -set option:distort:viewport \
    "%[fx:min(w,h)]x%[fx:min(w,h)]+%[fx:max((w-h)/2,0)]+%[fx:max((h-w)/2,0)]" \
    -filter point -distort SRT 0  +repage  viewport_square_2.gif

[IM Output]
Cortesia da Página de Tidbits de Fred Weinhaus. Uma técnica usando múltiplas técnicas de processamento de imagem para fazer a mesma coisa é mostrada em Miniaturas, Preenchimento e Recorte Quadrado.

Recorte por Proporção de Aspecto

Essa técnica pode ser expandida para que se recorte uma imagem centralizada de modo a ajustar-se a uma dada proporção de aspecto. Veja também a Discussão do Fórum Recorte por Proporção de Aspecto.

Outros Exemplos de Viewport

Veja também Métodos de Rotação de Imagens abaixo para outros exemplos de uso de um viewport para controlar qual parte do espaço distorcido é visível nos resultados.

Escalonamento de Saída e Super Amostragem

[-define](https://imagemagick.org/command-line-options/#define) distort:scale=N
[-set](https://imagemagick.org/command-line-options/#set) option:distort:scale N

Foi adicionado no IM v6.4.2-6, como um fator geral de escalonamento da imagem de saída. Isso amplia a imagem de saída pelo fator dado e, assim, o "[-distort](https://imagemagick.org/command-line-options/#distort)" precisará gerar N2 mais 'amostras' de consulta distorcida. O número geralmente é um inteiro, mas pode ser um fator de ampliação de ponto flutuante. Note que muitas distorções também permitem 'escalar' o tamanho da imagem distorcida resultante, contudo o tamanho da imagem resultante não seria afetado por esse escalonamento (a menos que um "[+distort](https://imagemagick.org/command-line-options/#distort)" de 'melhor ajuste' fosse usado). Essa configuração de 'scale', porém, não altera o conteúdo da imagem resultante de forma alguma, apenas amplia ou reduz a imagem de saída resultante. Isso pode ser usado, por exemplo, com um 'viewport' apropriado para produzir uma imagem que você pode facilmente "[-resize](https://imagemagick.org/command-line-options/#resize)" para um tamanho específico, permitindo gerar um 'zoom' controlado na imagem distorcida, sem perda de qualidade. Por exemplo, damos um 'zoom' na cabeça do coala. |

  magick koala.gif -set option:distort:scale 2.5 \
          -set option:distort:viewport 44x44+15+0 \
          -distort SRT 0  +repage koala_zoom.gif

[IM Output]
Note que, embora o viewport tenha sido solicitado como 44x44 pixels, a imagem de saída real foi escalada para 110x110 pixels. Mais comumente, é usado como um meio simples de 'Super Amostragem' (veja acima) da operação de distorção. Para isso, um fator inteiro de escala de 'super amostragem' é usado, e após a distorção a imagem é escalada de volta ao seu tamanho original, para mesclar as amostras extras e produzir um resultado de maior qualidade. |

  magick koala.gif -filter point -set option:distort:scale 10 \
          -distort SRT 0  -scale 10%   koala_super.gif

[IM Output]
Além disso, como a 'Reamostragem por Área' não é necessária ao usar 'Super Amostragem' para melhorar a qualidade da imagem (só a torna mais lenta), ela é tipicamente desligada usando uma opção "[-filter](https://imagemagick.org/command-line-options/#filter) point" (veja a seção anterior).


Introdução aos Métodos de Distorção

Distorção Scale-Rotate-Translate (SRT)

Uma das distorções mais simples, mas provavelmente uma das mais versáteis, é a distorção 'SRT' ou 'Scale-Rotate-Translate'. (SRT é apenas uma abreviação rápida) Você já viu o exemplo 'no-op' dessa distorção nos exemplos acima, em que a imagem é processada sem que nenhuma distorção real seja aplicada a ela, embora ainda seja filtrada, o que pode induzir um borramento muito leve. Aqui está uma repetição dos resultados da distorção 'no-op' acima...

  magick koala.gif    -distort SRT 0    koala_noop.gif

[IM Output] [IM Output]

| _Note que a imagem será borrada muito levemente como consequência do uso deReamostragem por Área. Contudo, os filtros de reamostragem do IM foram propositalmente projetados para minimizar esse borramento na distorção No-Op, e isso é necessário para uso normal.

Se você quiser uma distorção 'no-op' perfeita para propósitos especiais, então desative a reamostragem EWA. Ou seja, especifique o filtro 'no-op' "-filter Point" antes do operador de distorção no comando acima.


---|---
A distorção 'SRT' é, na verdade, três distorções separadas em um único método de distorção, e é por isso que ela é chamada de distorção 'Scale-Rotate-Translate'. Todos os argumentos, exceto a rotação do _ângulo
, são opcionais, e isso torna os argumentos altamente variáveis, dependendo exatamente de quantos argumentos separados por vírgula ou espaço você fornece, até o máximo de 7 números de ponto flutuante. **-distort SRT "** |

                  Angle

| **"** | -> rotação centralizada
---|---|---|---

        Scale     Angle

| -> escala e rotação centralizadas

X,Y               Angle

| -> rotação em torno da coordenada dada

X,Y     Scale     Angle

| -> escala e rotação em torno da coordenada

X,Y ScaleX,ScaleY Angle

| -> idem

X,Y     Scale     Angle  NewX,NewY

| -> escala, rotação e translação da coordenada

X,Y ScaleX,ScaleY Angle  NewX,NewY

| -> idem
O que isso faz é pegar uma imagem que você selecionou e um ponto de controle opcional. Se nenhum ponto de controle for fornecido, o centro exato da imagem de origem de entrada é usado. Em torno desse ponto, a distorção irá, em sequência... Escalar a imagem, Rotacioná-la e então Transladar ou mover o ponto de controle selecionado para uma nova posição. Daí o nome dessa distorção. A ordem dos argumentos mostrada acima reflete a ordem das operações que são efetivamente aplicadas à imagem. X,Y para transladar o 'centro' das transformações até a origem, ScaleX,ScaleY escalar a imagem, Angle rotacionar a imagem e então NewX,NewY transladar o 'centro' para essas coordenadas. Ou seja, o operador na realidade representa 4 operações internas de distorção, todas aplicadas simultaneamente como uma única distorção. Embora, para nós humanos, apenas 3 distorções distintas estejam envolvidas. Então vamos pegar um exemplo simples usando a imagem 'koala'... Um argumento é apenas uma rotação simples em torno do centro da imagem, produzindo basicamente um resultado semelhante ao do antigo Operador Rotate, mas sem qualquer aumento no tamanho da imagem. |

  magick koala.gif  -background skyblue  -virtual-pixel background \
          -distort ScaleRotateTranslate -110 koala_srt_rotate.png

[IM Output]
Note que, por padrão, o tamanho da imagem de entrada também é usado para a imagem de saída, de modo que a imagem rotacionada pode ser recortada. Ela também fica perfeitamente centralizada, independentemente de a imagem ter um número par ou ímpar de pixels. Usando a forma 'plus' de "+distort" e uma limpeza dos deslocamentos resultantes da tela virtual, podemos gerar algo muito semelhante ao Operador Rotate normal. |

  magick koala.gif  -background skyblue  -virtual-pixel background \
          +distort ScaleRotateTranslate -110 +repage koala_srt_rotate2.png

[IM Output]
| A partir do IM 6.7.3-4, oOperador Rotate agora usa a Distorção SRT do Distort. Antes disso ele usava Operações Shear, que não produziam um resultado tão bom.
---|---
Vamos também reduzi-la em 30%, mas usando um fundo transparente. |

  magick koala.gif  -alpha set -virtual-pixel transparent \
          +distort ScaleRotateTranslate '.7,-110' +repage koala_srt_scale.png

[IM Output]
O próximo conjunto de argumentos especificará o 'centro' em torno do qual a imagem é rotacionada e escalada. Esse ponto é chamado de 'ponto de controle' ou 'alça' na imagem, que é uma localização usada para controlar a distorção. Como estamos usando um ponto específico para essa distorção, vamos não usar o modo 'best-fit' para evitar as complicações dos 'deslocamentos virtuais'. Por exemplo, vamos rotacionar e escalar o koala em torno de seu 'nariz', localizado em 28,24 na imagem de origem. E já que estamos nisso, vamos distorcer as escalas X e Y de forma diferente. |

  magick koala.gif  -background skyblue -virtual-pixel background \
          -distort ScaleRotateTranslate '28,24  .4,.8  -110' \
          koala_srt_center.png

[IM Output]
E como exemplo final, vamos também mover o 'nariz' para perto da parte inferior da imagem e definir o fundo como um fundo branco correspondente. |

  magick koala.gif  -virtual-pixel white \
          -distort ScaleRotateTranslate '28,24  .4,.8  -110  37.5,60' \
          koala_srt_trans.png

[IM Output]
Note que a posição final também é um valor de ponto flutuante. De fato, todos os argumentos podem ser valores de ponto flutuante, e a distorção fará a coisa certa. Lembre-se de que cada uma das operações, Scale, Rotate e Translate, é executada nessa ordem. Como você pode ver, essa distorção é muito versátil, e embora você possa pensar nela como distorcendo a imagem usando três métodos diferentes em sequência, na realidade ela aplica as três distorções simultaneamente para produzir o resultado mostrado. Isso a torna mais rápida do que fazer múltiplos operadores individuais e geralmente produz um resultado final melhor. O exemplo acima também demonstra o uso de diferentes configurações de Pixel Virtual para definir a cor usada nas áreas referenciadas fora da imagem de origem real. Para ver o efeito da Interpolação em rotações, veja Interpolação de uma Linha e Borda Rotacionadas. Essa distorção foi especificamente projetada para pegar uma imagem e gerar uma animação com base nos movimentos e na rotação daquele objeto. Por exemplo, aqui eu crio uma nave espacial estilizada, que então animo de forma bem grosseira. A nave repousa sobre sua base em 20,75 (para a escala inicial de 'agachamento'), enquanto a 'alça' normal para movimento e rotações é o centro da nave, localizado em 20,60 na imagem original. Esses pontos representam pontos de controle pelos quais o objeto pode então ser animado de forma simples.

  magick -size 80x80 xc:skyblue -fill yellow -stroke black \
          -draw 'path "M 15,75 20,45 25,75 Z  M 10,55 30,55" ' \
          spaceship.gif
  magick spaceship.gif \
          \( -clone 0  -distort SRT '20,75  1.0,0.6  0' \) \
          \( -clone 0  -distort SRT '20,60     1     0  20,49' \) \
          \( -clone 0  -distort SRT '20,60    0.9   20  27,35' \) \
          \( -clone 0  -distort SRT '20,60    0.8   45  40,23' \) \
          \( -clone 0  -distort SRT '20,60    0.5   70  55,15' \) \
          \( -clone 0  -distort SRT '20,60    0.3   75  72,11' \) \
          \( -clone 0  -distort SRT '20,60    0.1   80  100,8' \) \
          -set delay 50  -loop 0  spaceship_launch.gif

[IM Output] [IM Output]

É claro que este é um exemplo bem grosseiro de como você pode usar uma distorção '[SRT](#srt)' para animar uma imagem estática, mas você deve captar a ideia. Você pode adicionar mais quadros e talvez algumas chamas e fumaça para aprimorá-lo ainda mais (contribuições são bem-vindas e o melhor resultado será adicionado aqui com o seu nome).

Métodos de Rotação de Imagens

Imagens podem ser rotacionadas de muitas maneiras. Mas apenas rotações simples podem não ser o que você está procurando. Rotacionar a imagem sem mudar o tamanho... |

  magick rose: -virtual-pixel black -distort SRT '20'  rotate_normal.png

[IM Output]
Ou rotacionar de modo a não recortar nenhuma parte da imagem rotacionada... |

  magick rose: -virtual-pixel black +distort SRT '20'  rotate_noclip.png

[IM Output]
No entanto, normalmente você não quer ver o Pixel Virtual 'preto' (ou qualquer outra cor que não seja da imagem) ao redor da imagem propriamente dita. Uma solução é recortar a imagem (usando uma Configuração de Viewport do Distort) para o maior retângulo de mesma proporção, de modo que ele contenha apenas pixels reais da imagem resultantes da rotação. Contudo, calcular esse retângulo é bastante complicado e foi bastante discutido no Fórum do ImageMagick usando algumas equações encontradas no Math Help Forum. Aqui rotacionamos e fazemos um recorte interno o mais próximo possível da proporção original. |

  angle=20
  ratio=`magick rose: -format \
     "%[fx:aa=$angle*pi/180; min(w,h)/(w*abs(sin(aa))+h*abs(cos(aa)))]" \
     info:`
  crop="%[fx:floor(w*$ratio)]x%[fx:floor(h*$ratio)]"
  crop="$crop+%[fx:ceil((w-w*$ratio)/2)]+%[fx:ceil((h-h*$ratio)/2)]"
  magick rose: -set option:distort:viewport "$crop" \
          +distort SRT $angle +repage   rotate_internal.png

[IM Output]
Isso parece complexo, mas é porque na verdade precisa calcular 4 valores separados para definir a Configuração de Viewport: Largura, Altura e deslocamento na imagem original. Outra alternativa é não apenas rotacionar, mas também escalar a imagem um pouco maior de modo a 'preencher' os limites da imagem original. |

  angle=20
  magick rose: -distort SRT \
     "%[fx:aa=$angle*pi/180;(w*abs(sin(aa))+h*abs(cos(aa)))/min(w,h)], $angle" \
     rotate_correction.png

[IM Output]
Este último é ideal para uma Correção de Rotação Menor de Fotos, de modo a preservar o tamanho original da imagem. A única razão pela qual esse método é mais simples é porque apenas um valor de 'escala' precisa ser calculado e, como tal, pode ser feito 'in-line'.

Distorções Usando Pontos de Controle

Enquanto o método de distorção '[SRT](#srt)' é definido especificando ângulos de rotação e fatores de escala, a maioria das distorções é definida movendo 'pontos' na imagem de origem e movendo-os para uma nova posição na imagem resultante. Isso é um pouco como o movimento do ponto 'centro' ao definir uma translação '[SRT](#srt)'. Esses pontos são chamados de pontos de controle e são mais comumente definidos fornecendo 4 valores de ponto flutuante (2 pares de coordenadas) para cada ponto de controle individual. Portanto, muitas vezes uma distorção é definida em termos de múltiplos conjuntos de 4 valores. Por exemplo....

X1,Y1 I1,J1 X2,Y2 I2,J2 X3,Y3 I3,J3 X4,Y4 I4,J4 . . . .

Onde o ponto de controle Xi,Xi na imagem de origem (relativo à sua tela virtual) é mapeado para Ii,Ji na imagem de destino distorcida. No entanto, como oOperador Distort na verdade mapeia coordenadas de destino para coordenadas de origem (veja Mapeamento Reverso de Pixels), o uso interno do acima é mapear coordenadas I,J para coordenadas X,Y. O resultado, no entanto, deve ser o mesmo, apenas uma forma diferente de pensar.
Antes da versão IM 6.3.6-0, quando oOperador Distort foi introduzido pela primeira vez, a ordenação de coordenadas para pontos de controle era definida como todas as coordenadas de origem, seguidas de todas as coordenadas de destino. Isso, no entanto, tornava muito difícil determinar quais coordenadas de origem e de destino correspondiam entre si e não permitia o simples acréscimo de mais pontos de controle para refinar ainda mais uma distorção.
--- ---
Isso é definido dessa forma para que o movimento de cada ponto de controle individual seja mantido junto na lista de valores de ponto flutuante separados por vírgula (ou espaço). Isso também permite o uso futuro de 'arquivos de pontos de controle' externos. A distorção mais simples que usa pontos de controle é a distorção '[Affine](#affine)', embora esta, como você verá mais adiante, seja normalmente definida em termos de três pontos, você pode usar apenas um ou dois movimentos de ponto de controle. Na verdade, a '[SRT](#srt)' é simplesmente um subconjunto de dois ou um ponto de uma distorção '[Affine](#affine)'. Por exemplo, aqui movemos o 'nariz' da nossa imagem de koala em '28,24' para a nova posição '45,40' (como indicado pela seta vermelha), o que resulta em uma simples 'translação' da localização da imagem.
  magick koala.gif  -virtual-pixel white \
          -distort Affine '28,24 45,40'   koala_one_point.png

[IM Output] [IM Output]

Com dois pontos, a distorção '[Affine](#affine)' pode não apenas transladar uma imagem, mas também escalá-la e rotacioná-la (toda a gama de uma distorção '[SRT](#srt)'). Por exemplo, aqui eu mapeio as 'orelhas' do koala (a linha vermelha de '30,11' e '48,29') para uma posição horizontal maior (uma linha azul de '15,15' a '60,15'), exigindo que a imagem seja escalada, rotacionada e transladada de modo que os pontos de controle sejam movidos para essa nova posição.

  magick koala.gif  -virtual-pixel white \
          -distort Affine '30,11 15,15  48,29 60,15'   koala_two_point.png

É claro que uma distorção '[SRT](#srt)' poderia ter reproduzido a distorção '[Affine](#affine)' de dois pontos acima, exceto que aqui definimos a distorção de uma forma diferente. Qual forma você deve usar depende de você, dependendo do que você está tentando alcançar.

Coordenadas de Imagem vs. Coordenadas de Pixel

O uso de pontos de controle no caso geral é direto, mas torna-se mais difícil quando você precisa alinhar uma imagem distorcida com outra imagem ou com construções desenhadas. A razão é que, enquanto a maioria dos operadores no IM trata as coordenadas em termos de 'Posições de Pixel ' (por exemplo, ao Recortar, Desenhar, etc.), as distorções lidam com coordenadas em 'Coordenadas de Imagem ' matemáticas. O que você precisa lembrar é que os pixels em uma imagem não são um 'ponto', mas na verdade uma 'área', de 1 unidade de pixel de tamanho. Ou seja, um pixel localizado em 10,10define uma área quadrada de cor, indo de 10unidades para baixo/através até 11unidades para baixo e através. Em termos de coordenadas de imagem, o 'centro' do pixel na verdade está localizado em 10.5,10.5. Ou seja, 0.5 precisa ser adicionado quando você está distorcendo uma imagem para mover o centro de um 'pixel' para uma localização específica. Assim, para reposicionar os 'pixels' de canto de uma imagem, você precisaria mover a imagem em termos dos pixels localizados em 0.5,0,5e _Largura_ -0.5,_Altura_ -0.5. Por outro lado, para reposicionar a imagem em termos das 'bordas' reais da imagem, você simplesmente usaria as coordenadas 0.0,0,0e _Largura_ ,_Altura_. Você só precisa pensar sobre o que realmente quer posicionar: o centro dos 'pixels' de uma imagem ou as 'bordas' da imagem. Ou se isso realmente importa para o seu problema em particular. Lembre-se de que, se você quiser desenharoutros elementos sobre sua imagem distorcida, precisará fornecer as posições de desenho em termos de 'Posições de Pixel '. E sim, o operador "-draw" pode desenhar linhas, círculos e outras formas usando valores de ponto flutuante. Da mesma forma, a largura do traço e/ou os raios dos objetos também podem ser fornecidos como valores de ponto flutuante. [IM Output] [IM Output]

| _Uma largura de traço de desenho menor que 1.0 não funciona bem (vejaDesenhando Linhas). Além disso, o preenchimento de área adiciona 0.5 extra (correspondendo ao acréscimo da largura do traço) às bordas da área de preenchimento (veja Limites de Preenchimento do Draw). Isso é feito independentemente da largura de traço realmente usada.

Para mais informações, veja Limites de Preenchimento do Draw. Algo que considero um bug._

Pontos de Controle Usando Escapes de Porcentagem

Você também pode usar Escapes de Porcentagem dentro dos argumentos de distorção. Por exemplo, você pode extrair atributos de imagem de uma imagem e então usá-los para redimensionar outra imagem de modo a corresponder à primeira. Aqui eu capturo o tamanho da imagem interna "rose:" e então uso uma distorção '[Affine](#affine)' para redimensionar a imagem "logo:" maior para o mesmo tamanho (sem preservar a proporção). |

   magick rose: -set option:rw %w -set option:rh %h +delete \
           logo: -alpha set -virtual-pixel transparent \
           +distort Affine '0,0 0,0     %w,0 %[rw],0   0,%h  0,%[rh]' \
           +repage logo_sized_as_rose.png

[IM Output]
Note que o distort gerará uma 'imagem em camadas' ligeiramente maior sobre uma tela virtual (incluindo um deslocamento negativo), razão pela qual precisei incluir um "[+repage](https://imagemagick.org/command-line-options/#repage)" no exemplo acima. Ela também terá bordas difusas, pois o distort gera uma distorção exata ou verdadeira da imagem, e não uma Imagem Redimensionada ortogonal higienizada. Para exemplos mais avançados de uso do Operador Distort para redimensionar imagens, exatamente como o Operador Resize faz, veja Distort vs Resize, bem como o Método Distort Resize abaixo. Você também pode usar escapes de porcentagem para calcular distorções com base na posição de uma imagem dentro da lista de imagens atual. Exemplos disso são fornecidos em Distorções Animadas.

Ajuste por Mínimos Quadrados de Pontos de Controle

Se você fornecer mais de 3 pontos de controle para a distorção '[Affine](#affine)', ou mais de 4 pontos para as distorções '[Perspective](#perspective)' ou '[Bilinear](#bilinear)', o ImageMagick realizará uma média por mínimos quadrados sobre todos os pontos fornecidos para encontrar uma representação 'média' para essas distorções. Isso significa que, se você está tentando alinhar uma imagem com outra (uma técnica conhecida como 'Registro de Imagem '), você pode definir mais do que o número mínimo de pontos necessários, de modo que o resultado seja uma distorção mais precisa. É claro que, se um ou mais desses pontos não 'se ajustar' bem com os outros pontos, o resultado será distorcido pelo ponto 'estranho', pois o IM tenta encontrar o melhor ajuste usando todos os pontos de controle fornecidos, incluindo o ruim. Alguma verificação para encontrar e remover 'pares de coordenadas ruins' pode ser necessária em algumas situações.

Pontos de Controle a partir de Arquivos

A lista de números (argumentos) de uma distorção também pode ser lida de um arquivo usando a sintaxe '@filename', assim como você pode inserir texto para coisas como "[-annotate](https://imagemagick.org/command-line-options/#annotate)" e "[label:](text.html#label)" (veja Caracteres de Escape em Argumentos de Texto). Por exemplo, você pode especificar uma distorção assim...

  magick input.png  -distort Perspective '@file_of_coords.txt' output.png

O nome do arquivo pode ser apenas um '@-' para significar ler o arquivo da entrada padrão. O arquivo em si será lido como uma string e tratado como a lista de coordenadas (argumentos) necessárias para a distorção envolvida. Como os números podem ser separados por vírgula ou espaço em branco, isso significa que os pares de coordenadas podem ser ordenados de forma limpa, um par de coordenadas por linha, na forma...

   X1   Y1   I1   J1
   X2   Y2   I2   J2
   X3   Y3   I3   J3
   X4   Y4   I4   J4
   ....

Isso, com o Ajuste por Mínimos Quadrados, torna o uso do registro de imagem muito prático. Como o arquivo é apenas uma lista de quatro números por linha, você pode usar outras ferramentas de script de processamento de texto, como "cut", "paste", "column", e ferramentas mais avançadas de script de processamento de texto, como "sed", "awk", "perl", etc., para manipular as coordenadas. O uso de arquivos de coordenadas e de argumentos de distorção se tornará mais importante com distorções mais avançadas, como a distorção '[Shepards](#shepards)' e as futuras distorções planejadas 'Grid' e "Mesh', onde centenas de pares de coordenadas podem estar envolvidos.


Métodos de Distorção Afim (Três Pontos)

Distorção Afim

Tanto a distorção '[SRT](#srt)' quanto as formas de um e dois pontos da distorção 'Affine' mostradas acima são, na verdade, simplificações de uma forma completa de 3 pontos da distorção 'Affine'. De fato, se você estudar a saída "-verbose" de qualquer distorção '[SRT](#srt)' (veja configuração verbose de distort para um exemplo), verá que internamente ela realmente é uma distorção '[AffineProjection](#affine_projection)' (veja abaixo). O único efeito de distorção que os métodos acima não conseguiam tratar completamente era o de 'cisalhamentos' semelhantes aos que o Operador Shear forneceria. Para isso você precisa usar uma distorção afim de três pontos. Você pode pensar nela como sendo uma distorção de três pontos, imaginando o primeiro mapeamento de coordenada como uma 'origem', com os outros dois mapeamentos de coordenadas como vetores a partir dessa origem. Por exemplo, aqui eu desenho algum texto e sobreponho um 'vetor' vermelho e azul para definir os três pontos de controle relativos a esse texto. Agora, movendo as coordenadas (como Coordenadas de Imagem) dessas duas linhas, podemos transladar, rotacionar, escalar e cisalhar essa imagem de texto, para ajustá-la à nova localização dessas linhas.

  magick -background lightblue -fill Gray -font Candice \
      -size 100x100 -gravity center label:Affine\! \
      -draw 'fill blue stroke blue path "M 3,60 32,60 M 27,58 27,62 32,60 Z"' \
      -draw 'fill red  stroke red  path "M 3,60  3,30 M  1,35  5,35  3,30 Z"' \
      label_axis.png
  magick label_axis.png \
          -distort Affine ' 3.5,60.5   3.5,60.5
                           32.5,60.5  32.5,60.5
                            3.5,30.5  33.5,20.5' label_axis_distort_shear.png
  magick label_axis.png \
          -distort Affine ' 3.5,60.5   3.5,60.5
                           32.5,60.5  27.5,85.5
                            3.5,30.5  27.5,35.5' label_axis_distort_rotate.png
  magick label_axis.png \
          -distort Affine ' 3.5,60.5  30.5,50.5
                           32.5,60.5  60.5,80.5
                            3.5,30.5  30.5,5.5' label_axis_distort_affine.png

[IM Output] [IM Output] [IM Output] [IM Output]

No primeiro exemplo, apenas a terceira coordenada (referente à linha vermelha vertical) foi modificada, fazendo com que a imagem fosse cisalhada e esticada ao longo do eixo Y. É claro que isso não precisa se limitar apenas ao eixo Y. Exemplos posteriores fazem mudanças mais radicais na imagem, incluindo rotações e translações. É claro que o operador Annotate Text também pode inclinar texto real dessa mesma forma, embora apenas com alterações no ângulo. Esse operador não escalará nem ampliará o texto em alguma direção específica. Ou seja, ele pode rotacionar um 'vetor', mas não pode esticá-lo mais longo ou mais curto. Veja Uso do Argumento Annotate para uma tabela de exemplos. A distorção afim pode fazer esse tipo de distorção para qualquer imagem, e não apenas para texto desenhado. Afim usando menos ou mais de três pares de coordenadas Se apenas 1 ou 2 pares de pontos de controle forem fornecidos, o IM usará uma forma mais limitada de distorção afim para corresponder ao movimento desses poucos pontos. Por exemplo, com apenas 1 par de coordenadas, ele se limita a translações não escaladas da imagem. Com 2 pontos, ele se limitará a distorções '[Scale-Rotate-Translation](#srt)' (sem cisalhamentos). Veja a discussão anterior sobre Distorções Usando Pontos de Controle para exemplos. Se mais de 3 pontos de controle forem fornecidos a uma distorção '[Affine](#affine)', então o IM usará Ajuste por Mínimos Quadrados para encontrar a melhor distorção afim de '3 pontos' que corresponda a todos os pares de coordenadas fornecidos. Isso significa que os pontos de controle da imagem de origem podem não mapear exatamente para os pontos de controle da imagem de destino, mas para uma 'média' de melhor ajuste de todos os pontos fornecidos. Por exemplo, se você tiver uma digitalização de um documento, poderia localizar e mapear todos os 4 cantos do documento para uma distorção afim que corrija a rotação e a escala do documento. Dessa forma, você pode obter um melhor ajuste 'médio' baseado em 4 pontos em vez de 3 pontos. Observe que, embora mais coordenadas possam produzir uma distorção melhor e mais precisa, se um par de coordenadas for muito ruim, então o ajuste por mínimos quadrados pode não produzir um bom ajuste de forma alguma. Alguma verificação para eliminar 'pares de coordenadas ruins' pode ser necessária. Future: Add some code to IM to report how 'accurate' each input coordinate pair is relative to the others to help determine what 'bad points' should be eliminated by the user.

Distorção Affine Projection

Como já mencionei, os diversos argumentos de uma distorção '[SRT](#srt)' e os pontos de controle de uma distorção '[Affine](#affine)' são matematicamente transformados em 6 números especiais que representam os 'coeficientes' de uma 'Affine Projection'. Esses números em uma Affine Projection são os coeficientes usados para o Mapeamento Direto de pontos da imagem de origem para a imagem de destino. Ou seja, são os valores matemáticos usados para mapear um x,y da imagem de origem para um i,j da imagem de destino. Os 6 argumentos de ponto flutuante são (na ordem em que devem ser fornecidos)...

sx, rx, ry, sy, tx, ty

Estes, por sua vez, formam as expressões de distorção.. Xd = | sx*Xs + ry*Ys + tx | , | Yd = | rx*Xs + sy*Ys + ty |
---|---|---|---|---|---
Onde "Xs,Ys" são as coordenadas da imagem de origem e "Xd,Yd" são as coordenadas da imagem de destino. Internamente, o Distort do ImageMagick reverterá as equações acima para fazer o Mapeamento de Pixels apropriado, mapeando as coordenadas "Xd,Yd" para buscar a cor em "Xs,Ys" na imagem de origem. Para mais informações sobre como os diversos valores da Matriz de Affine Projection afetam a imagem, veja a subpágina Transformações da Matriz Afim. Se você já tem esses coeficientes pré-calculados (digamos, extraídos da Saída Verbose de distort, ou os calculou você mesmo usando outros métodos a partir de outras formas de argumentos de entrada), então você pode fornecê-los diretamente ao IM para distorcer a imagem. Por exemplo, aqui eu 'cisalho' a imagem, mas usando um ângulo para calcular os coeficientes, em vez do movimento de pontos de controle. |

   angle=-20
   tan=`magick xc: -format "%[fx:tan( $angle *pi/180)]" info:`
   magick koala.gif -alpha set -virtual-pixel Transparent \
           +distort AffineProjection "1,$tan,0,1,0,0" +repage \
           koala_affine_proj.png

[IM Output]
A maneira mais antiga de fazer essa distorção no ImageMagick era usar o par operacional "-affine" e "-transform". Entretanto, a partir do IM v6.4.2-8, isso é apenas uma simples chamada a 'AffineProjection' usando a forma 'plus' ou 'bestfit' do Operador Distort. Veja a subpágina Transformações da Matriz Afim para mais detalhes.

Exemplos de Distorção Afim

Ladrilhamento Afim

Todos os três métodos de distorção do tipo afim que examinamos até aqui também oferecem maneiras interessantes de gerar diversos padrões de ladrilhamento, com base em uma imagem distorcida.

  magick checks.png    -alpha set    -virtual-pixel tile \
          -distort  ScaleRotateTranslate  '20,20  .5  30' \
          checks_srt_tile.png
  magick checks.png    -alpha set    -virtual-pixel tile \
          -distort  Affine  '0,0 10,10   0,89 10,50   89,0 50,0' \
          checks_affine_tile.png
  magick checks.png    -alpha set    -virtual-pixel tile \
          -distort  AffineProjection  '0.9,0.3,-0.2,0.7,20,15' \
          checks_amatrix_tile.png

[IM Output] [IM Output] [IM Output] [IM Output]

Usar um mapeamento de distorção dessa forma é, na verdade, como o 'mapeamento de textura' funciona em bibliotecas gráficas 3D e jogos. A única diferença é que eles mapeiam coordenadas tridimensionais de superfícies de volta para uma imagem bidimensional. Mesmo a distorção 'no-op' ("-distort SRT 0"), com uma Viewport de Distort apropriada, fornece uma maneira útil de ladrilhar sequências inteiras de imagens, como os Ladrilhos de Glitter Animados.

  magick glitter_blue.gif -virtual-pixel tile \
          -filter point -set option:distort:viewport 100x100 -distort SRT 0 \
          glitter_blue_tiled.gif

[IM Output] [IM Output]

Observe que também usei um "[-filter](https://imagemagick.org/command-line-options/#filter) point" para desligar a Reamostragem EWA, de modo a acelerar a operação, bem como garantir uma cópia perfeita (não amostrada) dos pixels da imagem de origem. A Viewport de Distort também pode especificar um deslocamento, de modo a 'rolar' as imagens ladrilhadas na imagem resultante.

Cubos 3D, usando Camadas Afins

A distorção '[Affine](#affine)', com seus pontos de controle, é ideal para gerar Cubos Ortográficos e Isométricos (veja na Wikipedia, Projeção Ortográfica e Projeção Isométrica para definições), a partir de três imagens. Tudo o que você precisa fazer é descobrir quatro pontos de controle em uma imagem de destino. Como usaremos uma Técnica de Camadas de Imagem, os pontos podem até ter valores negativos, e isso permite que o IM ajuste o tamanho final da imagem de acordo com as imagens deformadas geradas. Para este exemplo escolherei os pontos de controle '0,0' para o centro do cubo, e três pontos igualmente espaçados ao redor desse ponto central, em '-87,-50', '87,-50' e '0,100'. Tudo o que preciso fazer, então, é mapear os cantos apropriados de três imagens (de preferência quadradas) para esses pontos de controle. |

  magick \
     \( lena_orig.png -alpha set -virtual-pixel transparent \
        +distort Affine '0,512 0,0   0,0 -87,-50  512,512 87,-50' \) \
     \( mandrill_orig.png -alpha set -virtual-pixel transparent \
        +distort Affine '512,0 0,0   0,0 -87,-50  512,512 0,100' \) \
     \( pagoda_sm.jpg -alpha set -virtual-pixel transparent \
        +distort Affine '  0,0 0,0   0,320 0,100    320,0 87,-50' \) \
     \
     -background none -compose plus -layers merge +repage \
     -bordercolor black -compose over -border 5x2     isometric_cube.png

[IM Output]
Observe que usei as Coordenadas das bordas reais da imagem ao distorcer a imagem. Isso significa que, em termos matemáticos, as imagens devem se encaixar exatamente. Observe também que não simplesmente 'compus' (usando a Composição Alfa Over padrão) as imagens juntas. Se você fizesse isso, obteria 'lacunas' ligeiramente transparentes entre as imagens. A maneira correta (como mostrado) é usar a Composição Alfa Plus para unir peças 'conectadas pelas bordas', o que resultará em uma união perfeita, sem lacunas transparentes. Para mais informações, veja Alinhando Duas Imagens Mascaradas. Depois, adicionei uma borda extra e removi toda a transparência. Isso não é obrigatório, e você poderia facilmente usar qualquer fundo (ou "none"), mas fazê-lo destacará qualquer 'lacuna' que você possa ter em suas imagens.
[IM Output] Mostrada à direita está uma ampliação de uma dessas uniões na imagem, evidenciando a ausência de qualquer lacuna 'preenchida de preto' ao longo da união. Um método alternativo para criar um cubo isométrico, sem usar "-distort", é apresentado em Cubo Isométrico usando Cisalhamentos. Entretanto, essa técnica não permite usar coordenadas subpixel (não que eu tenha usado alguma no exemplo acima, mas poderia ter usado), estando restrita ao posicionamento de imagens usando coordenadas de pixel inteiro (inteiros).

Sombras 3D, usando Cisalhamentos Afins

Os mesmos métodos de camadas usados acima também podem ser utilizados para gerar sombras tridimensionais interessantes de formas estranhas. Isso adiciona uma sombra a qualquer forma 'plana' que esteja em pé. Por exemplo, vamos criar uma forma com uma base plana, de modo que possa ficar em pé. |

  magick -background None -virtual-pixel Transparent -fill DodgerBlue \
          -pointsize 72 -font Ravie  label:A   -trim +repage \
          -gravity South -chop 0x5  standing_shape.png

[IM Output]
Observe que a 'forma' tem uma base plana que também é a última linha da imagem. Isso é importante porque distorceremos a forma ao longo dessa linha, para que a sombra se conecte à forma em pé ao longo dessa linha. Aqui está o comando para gerar a sombra 3D a partir dessa 'forma em pé' |

  magick standing_shape.png   -flip +distort SRT '0,0 1,-1 0' \
          \( +clone -background Black -shadow 60x5+0+0 \
             -virtual-pixel Transparent \
             +distort Affine '0,0 0,0  100,0 100,0  0,100 100,50' \
          \) +swap -background white -layers merge \
          -fuzz 2% -trim +repage   standing_shadow.jpg

[IM Output]
O procedimento acima executa vários passos para alcançar o resultado mostrado. O mais complicado, porém, é a primeira linha. Ela inverte a imagem e depois faz um 'distort flip' de volta novamente. O resultado disso é que a linha inferior fica agora posicionada de modo a ter um valor Y=0 na tela virtual. Ou seja, a imagem inteira recebeu um deslocamento negativo para posicioná-la de forma que a linha inferior passe pela origem da tela virtual. Fazendo esse 'truque', podemos usar um 'cisalhamento afim' muito simples na 'sombra' extraída para distorcê-la. Assim, não precisamos saber o tamanho da imagem da forma para distorcer a sombra, mas ainda conseguimos manter tudo 'alinhado', pois todos permanecem sincronizados ao longo da linha inferior (Y=0) da imagem original. Você pode ajustar a direção em que a sombra cai e seu comprimento simplesmente ajustando a coordenada final ('100,50') do 'cisalhamento afim'. Os dois primeiros 'pares de coordenadas' não devem ser modificados, pois eles 'travam' a sombra na imagem original ao longo da linha inferior. Observe, entretanto, que até o último passo todas as imagens conterão deslocamentos negativos de tela virtual, então recomenda-se cautela se você planeja visualizar ou salvar as imagens de processamento intermediárias. O único problema com esse efeito de sombreamento é que ele é um 'desfoque universal'. Ou seja, a sombra não é realista. Na realidade, a sombra deveria ser nítida onde se une à 'forma em pé' e ficar mais desfocada à medida que a sombra se afasta. Isso, entretanto, pode ser feito usando um Mapeamento de Desfoque Variável, como o usado em Fonte de Sombra com Desfoque por Distância.

Sombra 3D, usando Compressão em Perspectiva

Esta é outra maneira de adicionar desfoque variável à sombra e, embora eu na verdade não a recomende, é bastante simples de implementar. Este exemplo foi desenvolvido antes de o Mapeamento de Desfoque Variável ser adicionado ao ImageMagick. Basicamente, você primeiro distorce a forma inicial da sombra usando uma Distorção em Perspectiva (examinada em detalhes abaixo), de modo a comprimir fortemente a 'parte distante' da sombra, desfocando-a, e depois expande essa compressão distorcendo-a até sua posição final de 'Cisalhamento Afim' que usamos acima. |

  magick standing_shape.png   -flip +distort SRT '0,0 1,-1 0' \
          \( +clone   -virtual-pixel Transparent -mattecolor None \
             +distort Perspective \
                '0,0 0,0  100,0 100,0   0,-100 45,-100   100,-100 60,-100' \
             -fuzz 2% -trim   -background Black -shadow 60x3+0+0 \
             +distort Perspective \
                '0,0 0,0  100,0 100,0   45,-100 -100,-50   60,-100 0,-50' \
          \) +swap -background white -layers merge \
          -fuzz 2% -trim +repage     standing_shadow_var.jpg

[IM Output]
Isso é quase exatamente igual ao Exemplo de Sombreamento 3D original, mas com alguns passos extras. A forma original é primeiro distorcida em um trapézio, depois qualquer espaço excedente é aparado para acelerar o passo seguinte. Em seguida, extraímos uma sombra desfocada da forma distorcida. Uma vez que a imagem da sombra foi criada a partir da imagem distorcida, os mesmos pontos de controle são usados para des-distorcer a imagem da sombra e movê-la para sua posição como um Cisalhamento Afim. A chave é que o desfoque da sombra acontece sobre uma imagem distorcida, que então é des-distorcida (e, neste caso, Cisalhada Afinamente, ao mesmo tempo). Como resultado, o desfoque também é distorcido e expandido, de modo a desfocar mais ao redor da parte superior da sombra e muito menos ao longo da linha de base. Como resultado do desfoque em perspectiva, obtemos um desfoque variável que deve atingir o pico a cerca de 100 pixels de distância da linha de base do chão. Conforme definido pelos pontos de controle iniciais do desfoque em perspectiva.

Redimensionar Imagens usando Distort

Tanto Distort quanto Resize são, na verdade, muito semelhantes em muitos aspectos. Ambos são operadores de distorção de imagem, e ambos usam Mapeamento Reverso de Pixels para criar a imagem resultante. Ambos também fazem uso da configuração "[-filter](https://imagemagick.org/command-line-options/#resize)" e de seus controles avançados, para a determinação de cor, embora o façam de maneira muito diferente. O Resize é uma operação de distorção de imagem simplificada (e muito mais comum), permitindo fazer muitas otimizações. Ele é alinhado ortogonalmente, permitindo que você use um método de filtragem ortogonal de imagem em 2 passagens no redimensionamento. Ou seja, ele primeiro dimensiona em uma direção, depois na outra, usando uma imagem temporária intermediária. Além disso, como o fator de escala é constante sobre toda a imagem de destino, com as bordas alinhadas a uma dimensão de pixel inteiro (inteiro), o algoritmo pode simplificar bastante seu processamento e os requisitos de cache do filtro que utiliza. Todas essas limitações permitem diversas otimizações que o tornam muito rápido em comparação com o trabalho que o distort precisa fazer. O Distort também pode Redimensionar Imagens, mas o faz em uma única passagem, que converte diretamente da imagem original para a nova imagem resultante. Ele não precisa alinhar as bordas a posições de pixel inteiro, e poderia rotacionar e escalar cada posição de pixel. Em outras palavras, é um operador muito mais geral, que exige a realização de muito processamento extra para cada pixel no resultado final, com menos oportunidades de otimização. Para fazer o Distort gerar uma imagem equivalente à do Resize, ele precisa seguir exatamente as mesmas limitações e usar alguns truques complexos de processamento de imagem. Isso foi discutido nos fóruns do IM, em Redimensionamento Correto (usando distorts), e resultou em uma técnica de redimensionamento por distort equivalente, baseada no uso do Método de Distorção Afim. O método de distorção 'Resize ' resultante foi adicionado ao ImageMagick versão 6.6.9-2. A versão de interface de linha de comando (CLI) dessa distorção aceitará e usará via magick exatamente o mesmo Argumento de Geometria que o Resize aceita, incluindo a leve discrepância nos fatores de escala para as duas dimensões, tornando-o uma alternativa direta de redimensionamento. |

  magick logo:  -distort Resize 150x  logo_resized.png

[IM Output]
| _Outras interfaces de API para o método de distorção 'Resize ' aceitarão apenas dois números como argumentos, que são tratados como o tamanho inteiro final da imagem resultante. Neste momento, elas não aceitarão um argumento de geometria real com seus diversos flags de controle de redimensionamento, que modificam o tamanho final da imagem. Ou seja, flags como porcentagem, apenas redimensionar maior/menor, ou mesmo a preservação da proporção de aspecto não estão disponíveis.

Cabe aos mantenedores dessas APIs adicionar tal suporte para esse método especial de distorção de imagem._
---|---
A real diferença entre o Distort Resize acima e o Operador Resize normal é que a versão por distort usa um Filtro Cilíndrico (elíptico) de passagem única, muito mais lento, para determinar a cor final de cada pixel. Em outras palavras, ele oferece uma comparação direta entre filtros ortogonais de 2 passagens (resize) versus filtros cilíndricos bidimensionais de uma única passagem (distort resize). Veja Distort vs Resize para uma dessas comparações.

Detalhes Internos do Distort Resize

A seguir estão as operações equivalentes que o Distort Resize acima realizou internamente.

  magick logo:  -alpha set -virtual-pixel transparent \
          +distort Affine '0,0 0,0   %w,0 150,0   0,%h 0,113' \
          -alpha off  -crop 150x113+0+0 +repage   distort_resize.png

Os valores '150' e '113' (usados em dois lugares) são o tamanho desejado da imagem final, arredondado para o inteiro mais próximo. Ele foi calculado para tentar preservar da melhor forma a proporção de aspecto da imagem, mantendo-se dentro da limitação de tamanho inteiro final. Eles são normalmente calculados pelo ImageMagick a partir do Argumento de Geometria de redimensionamento fornecido, usando uma função de API separada. Em seguida, ele habilita a transparência e os Pixels Virtuais transparentes, de modo que os 'pixels virtuais' externos não participem do cálculo da cor final do pixel. Quando a distorção é concluída, a transparência é novamente removida (desligada), e os pixels de 'buffer' adicionados pelo distort são removidos usando um Recorte de Imagem. Devido ao uso de pixels transparentes, o comando acima só funcionará corretamente para imagens que não contenham nenhuma transparência, como a imagem interna "logo:" exemplificada acima. Esta é a versão muito mais complexa, necessária para separar os efeitos dos Pixels Virtuais de qualquer possível transparência existente na imagem.

  magick logo: -alpha set -virtual-pixel transparent \
          \( +clone -alpha extract -alpha opaque \) \
          +distort Affine '0,0 0,0   %w,0 150,0   0,%h 0,113' \
          -alpha off -crop 150x113+0+0 +repage \
          -compose CopyOpacity -composite      distort_resize_trans.png

Isso faz duas distorções: primeiro para distorcer a imagem e depois para distorcer o canal alfa (transparência) separadamente, em cada caso usando a transparência para remover os efeitos de virtual-pixel. Como resultado, é pelo menos duas vezes mais lento que o caso em que não há transparência na imagem original. Ambas essas técnicas são implementadas internamente pelo Método Distort Resize. Como tal, este 'método' é, na verdade, uma 'macro' de conveniência para os usuários, e não realmente um método de distorção real, que é uma distorção 'afim'.


Métodos de Distorção de Quatro Pontos

Distorção de Perspectiva

Provavelmente o tipo de distorção mais solicitado tem sido uma operação rápida de distorção de perspectiva. Trata-se de uma distorção de 4 pontos, portanto requer pelo menos 4 conjuntos de pares de pontos de controle, ou 16 valores de ponto flutuante. Por exemplo, aqui tenho uma imagem de um edifício. A partir dessa imagem, descobri manualmente a localização de 4 pontos (vermelho). Também defini a localização final para a qual esses pontos foram transformados na imagem final (azul), de modo a 'endireitar' ou 'retificar' a fachada do edifício.

  magick building.jpg \
          -draw 'fill none stroke red polygon 7,40 4,124, 85,122, 85,2' \
          building_before.jpg
  magick building.jpg \
          -draw 'fill none stroke blue polygon 4,30 4,123, 100,123, 100,30' \
          building_after.jpg

[IM Output] [IM Output] [IM Output]

Para realizar a distorção de imagem propriamente dita, basta alimentar essas coordenadas no método 'perspective' de "-distort".

  magick building.jpg -alpha set -virtual-pixel transparent \
         -distort Perspective \
              '7,40 4,30   4,124 4,123   85,122 100,123   85,2 100,30' \
          building_pers.png

[IM Output] [IM Output]

Observe a área em branco no canto superior direito, onde a distorção 'não encontrou' os dados de pixel na imagem de origem. O que o IM faz nessa situação é controlado pela configuração "-virtual-pixel" (veja Virtual Pixel). O que é menos perceptível é que uma pequena parte da borda mais à esquerda da imagem original também é 'perdida' pelo mesmo motivo. A título de curiosidade, vamos também reverter a distorção, trocando as coordenadas de cada par de mapeamento. Isso permite ver o quanto da imagem é degradado pela distorção.

  magick building_pers.png  -alpha set -virtual-pixel transparent \
         -distort Perspective \
              '4,30 7,40   4,123 4,124   100,123 85,122   100,30 85,2' \
          building_pers_rev.png

[IM Output] [IM Output] [IM Output]

Nada mal. Há bastante 'granulação' presente, mas isso é inevitável. Observe que a 'granulação' é pior no lado direito da imagem, onde ela foi mais comprimida. Todas as distorções sofrem com esse problema de compressão; por isso, deve-se sempre tentar distorcer a partir de uma imagem original, em vez de distorcer uma imagem já distorcida. Aqui está outro exemplo do uso dessa transformação, usando a imagem de teste especial em tabuleiro de xadrez que criamos acima, que distorcemos e depois revertemos a distorção.

  magick checks.png        -alpha set    -virtual-pixel transparent \
          -distort Perspective '0,0,0,0  0,90,0,90  90,0,90,25  90,90,90,65' \
          checks_pers.png
  magick checks_pers.png   -alpha set    -virtual-pixel transparent \
          -distort Perspective '0,0,0,0  0,90,0,90  90,25,90,0  90,65,90,90' \
          checks_pers_rev.png

[IM Output] [IM Output] [IM Output]

Você pode ver a leve granulação causada pela compressão da imagem, mas a imagem está basicamente restaurada. O que de fato acontece é que o IM usa todos os pares de pontos de controle fornecidos para calcular os coeficientes apropriados de uma '[Perspective Projection](#perspectiveprojection)' (veja a seguir). Se você incluir uma configuração Verbose, poderá ver tanto os coeficientes quanto o DIY FX Equivalent que é usado internamente pelo IM para realizar essa distorção. Se apenas 3 ou menos pares de pontos de controle forem fornecidos, o IM automaticamente recorrerá à distorção mais simples '[Affine](#affine)'. Já mais de 4 pontos (para 'Registro de Imagem ') serão Ajuste por Mínimos Quadrados para encontrar a distorção que melhor se ajusta a todos os pontos de controle fornecidos. FUTURO: Alternativa. As quatro coordenadas também poderiam representar um triângulo e um ponto central. Você pode fixar o triângulo e mover o ponto central, ou fixar esse centro e mover as outras três coordenadas, para gerar a vista em perspectiva. Se quiser ver mais detalhes de como a distorção funciona, veja Detalhes Internos da Perspectiva abaixo. Você também pode consultar uma implementação em Postscript apresentada em um artigo em PDF Perspective Rectification, por Gernot Hoffmann. Dê também uma olhada em Leptonica Affine and Perspective Transforms.

Visualizando Horizontes Distantes

Você pode produzir alguns efeitos bastante incomuns usando Perspective Distortions se ajustar as coordenadas para produzir um 'ponto de fuga' dentro dos limites da imagem. |

  magick checks.png -mattecolor DodgerBlue \
          -virtual-pixel background -background Green \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          checks_horizon.png

[IM Output]
Bem, usamos 'Green' para os pixels virtuais que 'cercam' a imagem original, o que habilitamos usando Virtual Pixel Background Settings. Mas o mais interessante é o surgimento da cor 'azul' que foi definida usando a configuração "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)". Essa cor 'azul' representa uma área onde os pixels gerados pela distorção são inválidos , e em tais áreas o operador "-distort" simplesmente produzirá a configuração "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)". Para uma Perspective Distortion, qualquer pixel que termine no 'céu' da imagem resultante será classificado como inválido. Além disso, define-se o 'céu' como o lado do 'horizonte' no qual a imagem de origem não aparecerá. O 'céu' só aparecerá em imagens distorcidas em perspectiva quando a imagem resultante for muito comprimida pela distorção. Se você não quiser um 'céu' no resultado final da imagem, a melhor ideia é definir tanto "[-background](https://imagemagick.org/command-line-options/#background)" quanto "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" para usar a mesma cor. A Perspective Distortion fica mais interessante quando uma das configurações especiais de ladrilhamento infinito de Virtual Pixel é usada. Por exemplo, aqui usamos uma configuração '[tile](misc.html#tile)' para gerar um plano infinitamente ladrilhado. |

  magick checks.png  -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_tile.png

[IM Output]
Uma palavra de advertência sobre esta imagem. Solicitar uma imagem infinitamente ladrilhada é muito lento de gerar. Quanto maior a imagem, mais lento fica. Você pode monitorar o progresso do "[-distort](https://imagemagick.org/command-line-options/#distort)" (ou qualquer outra tarefa lenta de processamento de imagem) usando a "[-monitor](https://imagemagick.org/command-line-options/#monitor)" Operational Control Setting. Basicamente, para um único pixel próximo ao horizonte, o ImageMagick precisará calcular a média de um número enorme de pixels da imagem original para determinar a cor apropriada. Isso pode levar muito tempo. O ImageMagick tenta limitar o tempo que usa para tratar esses pixels próximos ao horizonte, armazenando informações em cache e usando algum conhecimento interno das várias configurações de Virtual Pixel, mas ainda assim pode demorar bastante. Para mais detalhes sobre este método, veja Reamostragem de Área acima. Outra imagem de perspectiva infinitamente ladrilhada pode ser gerada usando uma Random Virtual Pixel Setting... |

  magick checks.png  -virtual-pixel random -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_random.png

[IM Output]
O que acontece é que todos os pixels virtuais ao redor da imagem são apenas escolhas aleatórias de qualquer pixel dentro da própria imagem. O resultado é um solo composto de ruído aleatório que fica mais suave e mais desfocado à medida que se olha em direção ao horizonte da imagem. Isso dá uma sensação natural de profundidade, sem qualquer padrão de repetição específico. Aqui repeti o exemplo acima, mas com uma imagem de origem puramente em preto e branco. No entanto, não estou interessado na imagem distorcida em si, apenas no padrão 'random' de Virtual Pixel que foi gerado, então alterei qual parte do 'espaço da imagem distorcida' estou visualizando, usando uma configuração especial '-set option:distort:viewport'. Essa configuração substitui o tamanho e a localização normais da área do espaço distorcido que está sendo visualizada. Neste caso, uma área contendo apenas pixels virtuais, e não a imagem distorcida. |

  magick -size 90x90 pattern:gray50 -alpha set \
       -virtual-pixel random -mattecolor none \
       -set option:distort:viewport 120x120+100-15 \
       -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
       +repage -size 120x50 gradient:dodgerblue-tomato \
       -compose DstOver -composite    sunset_horizon.png

[IM Output]
Para completar a imagem, removi o deslocamento do viewport (usando "[+repage](https://imagemagick.org/command-line-options/#repage)" ) e apliquei Underlaid or DstOver um gradiente de cores de pôr do sol no 'céu' transparente (definido usando "[alpha setmattecolor](https://imagemagick.org/command-line-options/#mattecolor)") . Uma imagem bastante interessante que poderia ser usada como pano de fundo para algum outro trabalho de processamento de imagem. Você pode ajustar os parâmetros de distorção para ajustar a altura e a inclinação do horizonte. Aqui está um teste mais tradicional de uma distorção de perspectiva ladrilhada. |

  magick pattern:checkerboard -scale 120x120 -normalize \
          -virtual-pixel tile  -distort Perspective \
             '0,0 10,61   119,0 60,60   0,119 5,114   119,119 125,110' \
          checkered_plain.gif

[IM Output]
Em meus estudos, achei o teste acima enganoso, pois não dá nenhuma indicação real da qualidade da técnica de reamostragem de área para escalas próximas da unidade de uma imagem (área de primeiro plano, em vez de áreas distantes). Ou seja, uma observação atenta dos problemas de reamostragem como os descritos em Artefatos de Reamostragem. Esta última imagem também mostra um ponto de 'corte' próximo ao horizonte, onde o ImageMagick decidiu que não valia a pena tentar determinar a cor apropriada para um pixel (considerando a configuração atual de pixel virtual), mas abrevia o algoritmo EWA e usa a cor média da imagem inteira. Isso só é visível nesta imagem por causa do padrão diagonal de cor em grande escala presente na imagem. A cor média de uma imagem é calculada apenas uma vez por operação de distorção, e somente quando necessária pela primeira vez. Ao usá-la, o ImageMagick economiza uma quantidade enorme de tempo no cálculo de cores próximas ao horizonte, quando tipicamente o resultado será a cor média da imagem. Isso acontece quando ou a elipse se torna tão alongada que excede os limites de ponto flutuante, ou o número de pixels de amostragem (paralelogramo delimitador da elipse) torna-se 4 vezes maior que a imagem de origem de entrada. Isso atualmente não é configurável pelo usuário.

Caixas 3D, Camadas em Perspectiva

A forma 'mais' de "+distort", que garante que a imagem distorcida inteira seja preservada em uma camada corretamente posicionada (ou 'tela virtual'), é projetada de modo que, se os mesmos 'pontos de controle' forem usados para distorcer imagens, esses pontos se alinharão no 'espaço virtual'. Isso significa que, se as imagens forem Camadas Mescladas juntas, elas também se alinharão de acordo com os pontos de controle. Por exemplo, aqui geramos duas imagens, uma 'frente' e uma 'lombada', de modo que dois pontos de controle de borda fiquem alinhados entre si, para formar a lombada de uma caixa.

  # Generate a Spine Image
  magick -size 200x40 xc:skyblue \
    -pointsize 20 -gravity north -annotate +5+0 'IM Examples' \
    -pointsize 10 -gravity south -annotate +0+0 'ImageMagick' \
    -stroke blue -strokewidth 2 -draw 'line 30,0 30,40' \
    -rotate -90 box_spine.jpg

  # generate the front cover
  magick -size 150x200 xc:skyblue \
    -fill black -pointsize 20 -gravity north -annotate +0+5 'IM Examples' \
    -fill blue -pointsize 15 -gravity northeast -annotate +5+28 'Box Set' \
    -fill black -pointsize 15 -gravity south -annotate +0+5 'ImageMagick' \
    -stroke blue -strokewidth 2 -draw 'line 0,169 150,169' \
    \( logo.gif -resize 100x100 \) \
    -gravity center -compose multiply -composite box_front.jpg

  # Distort both images and merge using common points.
  magick \
    \( box_spine.jpg -alpha set -virtual-pixel transparent \
       +distort Perspective \
           '0,0 -30,20  0,200 -30,179  40,200 0,200  40,0 0,0' \) \
    \( box_front.jpg -alpha set -virtual-pixel transparent \
       +distort Perspective \
           '0,0 0,0  0,200  0,200  150,200 100,156  150,0 100,30' \) \
    \
    -background black -compose plus -layers merge  +repage \
    -bordercolor black -compose over -border 15x2    box_set.jpg

[IM Output] [IM Output] [IM Output]

Note também o uso de Plus Alpha Composition para juntar peças 'conectadas por borda'. Isso é necessário para evitar a geração de uma 'lacuna semitransparente' entre as duas imagens. Para mais informações, veja o exemplo 3D Cube acima, bem como Aligning Two Masked Images. Usar posições como essas significa que quase toda a imagem da 'lombada' é, na verdade, distorcida para uma posição 'x' negativa. A imagem resultante tem, portanto, um deslocamento negativo na tela virtual. O IM não tem problemas em fazer isso ao usar a versão em camadas "+distort" do operador. O operador Layers Merge também é projetado para tratar a sobreposição de imagens com deslocamentos negativos, 'costurando' as duas imagens de forma limpa. Ainda preciso usar um "+repage" final para remover esse deslocamento negativo da imagem final, depois de terem sido 'mescladas' juntas. Se eu não fizer isso, outros programas como navegadores web podem não entender tais deslocamentos negativos, causando efeitos indefinidos. O exemplo acima também foi colocado no script de shell "[box_set_example](../static/img/scripts/box_set_example) ", para que você possa baixá-lo e experimentá-lo de forma mais conveniente. Você pode ir além e também adicionar imagens espelhadas da 'caixa' sendo refletida pela superfície sobre a qual ela repousa, embora você também possa querer recolorir ou escurecer essa imagem de alguma forma para torná-la mais realista. Veja Reflexos para tais técnicas de espelhamento.
Um exemplo adicional em PHP foi desenvolvido em uma discussão sobre como envolver 'fotos' em uma moldura de tela sem borda. Veja Canvas wrap transformation, para mais detalhes.
Para finalizar, aqui está um exemplo fantástico de Jean-François Hren para www.animecoversfan.com, que foi amplamente discutido nos IM Discussion Forums.

[Diagram]

Esta imagem foi criada tomando uma imagem artística de uma capa de caixa de vídeo de anime, dividindo essa capa em 3 segmentos ('capa', 'lombada' e 'verso'), distorcendo cada um separadamente, em imagens em camadas, adicionando uma quarta imagem de 'disco' e mesclando tudo. A imagem foi então finalizada com a adição de efeitos de realce e sombreamento (usando composição de imagem HardLight) e a adição de efeitos de borda e sombra semitransparente (usando CopyOpacity). O mais impressionante é que todo o processo foi feito por um único comando "magick", a partir das imagens de entrada. É um excelente exemplo do que o IM pode fazer e do processo pelo qual um script de comando complexo pode ser gerado. Recomendo a leitura da discussão no fórum, pois contém muitas dicas, sugestões e técnicas gerais de depuração. (Mais exemplos contribuídos são bem-vindos)

Distorção por Projeção de Perspectiva

Assim como a distorção '[Affine](#affine)' pode ser tratada diretamente fornecendo os coeficientes matemáticos de uma '[Affine Projection](#affine_projection)', a '[Perspective](#perspective)' também pode ser tratada por 8 coeficientes de uma distorção 'Perspective Projection'. Como antes, esses números representam os coeficientes usados para o Forward Mapping de pontos da imagem de origem para a imagem de destino. Ou seja, são os valores matemáticos usados para mapear uma imagem de origem x,y para uma imagem de destino i,j. Os 8 argumentos de ponto flutuante são (na ordem dada)... sx, ry, tx, rx, sy, ty, px, py


Esses valores de coeficiente, por sua vez, formam a expressão.. Xd = | sx*Xs + ry*Ys + tx | , | Yd = | rx*Xs + sy*Ys + ty |
---|---|---|---|---|---


|


px*Xs + py*Ys + 1.0 | px*Xs + py*Ys + 1.0
Onde "Xs,Ys" são coordenadas da imagem de origem e "Xd,Yd" são coordenadas da imagem de destino. Internamente, o ImageMagick Distort reverterá as equações acima para realizar o Reverse Pixel Mapping apropriado, mapeando as coordenadas "Xd,Yd" para buscar a cor em "Xs,Ys" na imagem de origem. Os primeiros 6 valores da 'Perspective Projection' são, na verdade, os mesmos coeficientes da '[Affine Projection](#affine_projection)', embora estejam ligeiramente reordenados para serem mais lógicos (em termos de 'matemática de matrizes', os primeiros 6 elementos foram transpostos diagonalmente). Os dois argumentos extras px,py formam um divisor de escala para toda a distorção, o que faz a imagem parecer menor na direção específica de acordo com os valores fornecidos, dando assim à imagem distorcida o efeito de 'distância' da perspectiva. Se esses dois valores forem definidos como zero, a distorção 'Perspective Projection' torna-se equivalente a uma 'Affine Projection'. Por exemplo... |

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Perspective-Projection \
             '1.40, 0.25, 3.0    0.15, 1.30, 0.0    0.007, 0.009' \
          perspective_projection_rose.png

[IM Output]
Lembre-se de que a matriz que você fornece é a matriz projetiva direta, que mapeará as coordenadas da imagem de origem para as coordenadas da imagem de destino. Internamente, o ImageMagick reverterá a matriz para poder mapear as coordenadas da imagem de destino para as coordenadas da imagem de origem. Se quiser ver quais são esses valores, use a Opção Verbose de Distorção, para que o IM produza seus coeficientes internos como uma Expressão do Operador FX (veja a seguir).

Detalhes Internos da Perspectiva

Se você adicionar "-verbose" (veja Verbose Distortion Summery acima) logo antes da distorção de perspectiva, o IM produzirá dois operadores que devem ser substituições quase equivalentes ao operador "-distort". Um é uma versão "-fx" MUITO LENTA (Veja FX DIY operator. O outro será a matriz Perspective_Projection de mapeamento direto. Por exemplo... |

  magick rose: -alpha set -virtual-pixel transparent -verbose \
          -distort Perspective "0,0,3,0 0,46,10,46 70,0,70,7 70,46,60,40" \
          +verbose perspective_rose.png

[IM Output]
| [IM Text]


A primeira seção Perspective Projection pode ser usada para mapear coordenadas de origem em coordenadas de destino. A fórmula é como acima.

i = ( 1.430099*x +0.246650*y +3 )/( 0.006757*x + 0.009448*y +1 ) j = ( 0.147296*x +1.434591*y +0 )/( 0.006757*x + 0.009448*y +1 )


Um exemplo de extração e uso desses valores é mostrado no último conjunto de exemplos em Posicionando Imagens de Camada Distorcidas. Por outro lado, a segunda seção FX equivalente usa um conjunto diferente de 8 coeficientes, que realiza o Reverse Pixel Mapping que uma distorção de imagem realmente precisa aplicar. A saber...

x = ( 0.711858*i -0.108326*j -2.135575 )/(-0.004119*i -0.005877*j +1 ) y = (-0.073090*i +0.699571*j +0.219269 )/(-0.004119*i -0.005877*j +1 )


Note que, na fórmula FX equivelent de saída, os coeficientes divisores são usados primeiro, pois são comuns às equações de coordenada X e Y. Lembre-se de que todas as coordenadas que você fornece estão em coordenadas de imagem, não em coordenadas de pixel; veja Image Coordinates vs Pixel Coordinates para detalhes. Assim, qualquer posição de pixel precisará de 0.5 adicionado à coordenada de pixel de entrada, antes de aplicar o acima, e depois subtrair 0.5 da coordenada final, para convertê-la de volta em coordenadas de pixel (de desenho). Você pode ver isso sendo aplicado no código FX equivalent acima. O teste final no FX equivalent, logo antes da busca na imagem de origem, trata os pixels inválidos do 'céu', onde o destino não consegue mapear corretamente para a imagem de origem. No entanto, ele simplesmente substituirá 'blue' por tais pixels em vez do "-mattecolor", e não fornece nenhuma suavização de horizonte que o algoritmo interno fornece para a distorção de perspectiva.
Exemplo de mapeamento direto de perspectiva... Esses mapeamentos permitem converter uma coordenada específica de uma imagem em uma localização na outra imagem (em qualquer direção). Por exemplo, um ponto escuro no centro da imagem de origem da rosa está nas coordenadas de pixel '39,20'. Mapeando isso para coordenadas de imagem adicionando ½ para obter '39.5,20.5'. Agora podemos usar as equações de x,y para i,j para mapear isso em coordenadas de imagem de destino '44.2,24.1'. E, finalmente, para coordenadas de pixel de 'desenho', subtraindo ½, obtemos a posição final de '43.7,23.6'. E aqui marco essa coordenada usando um círculo tanto na imagem de entrada quanto na de saída..

  magick rose: -fill none -stroke black \
          -draw 'circle 39,20 39,24'    rose_marked.png

  magick perspective_rose.png -fill none -stroke black \
          -draw 'circle 43.7,23.6 43.7,26.6'  perspective_rose_marked.png

[IM Output] [IM Output]

Como você pode ver, o mesmo ponto na imagem distorcida em perspectiva foi corretamente localizado em ambas as imagens (até mesmo em nível de subpixel)!

Distorções Bilineares

Os métodos de distorção 'Bilinear' implementam outro tipo de distorção de 4 pontos. No entanto, este não é nem de longe tão direto quanto a distorção '[Perspective](#perspective)' que vimos acima. Mas, como você verá, é uma alternativa de distorção muito útil.

Distorção Bilinear Direta

Por exemplo, vamos pegar uma imagem de teste especial de um mandril que teve uma grade sobreposta a ela e distorcê-la com perspective e bilinear.

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort Perspective \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_pers.jpg
  magick mandrill_grid.jpg -alpha set -virtual-pixel black -interpolate Spline \
       -distort BilinearForward \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_blin.jpg

[IM Output]
Original | | [IM Output]
Perspective | [IM Output]
Bilinear
---|---|---|---

Primeiro, você deve notar que ambas as distorções mapearam corretamente a imagem de um conjunto de pontos de controle para o outro conjunto de pontos. Além disso, todas as linhas horizontais e verticais na imagem de origem também permanecem retas, em ambas as distorções. Porém, aí terminam as semelhanças. A perspective reduzirá o espaçamento entre as linhas de modo que até as linhas diagonais permaneçam retas. Isso resulta em áreas dos quadrados tornando-se menores e, assim, dando ao canto superior direito um aspecto realista de 'à distância'. A bilinear, por outro lado, não faz um lado da imagem parecer 'mais distante', nem tenta manter as linhas retas. O que ela tenta fazer é manter constantes todos os espaçamentos entre as linhas, mas isso resulta na linha diagonal tornando-se curva. Ou seja, ela preserva as razões de distância ao longo de qualquer linha dada. Isto é, os comprimentos relativos de cada segmento de linha permanecem os mesmos ao longo de todo o comprimento da linha, mesmo que a própria linha possa estar dobrada, curvada ou encurtada como um todo. Isso significa que o espaçamento da grade no exemplo acima permanece com escala constante em toda a imagem, e o quadrado distorcido no canto superior direito ainda tem aproximadamente o mesmo tamanho que o quadrado distorcido no canto inferior esquerdo. A imagem permanece com 'aspecto plano', apenas distorcida em uma forma diferente. Observe que a bilinear (direta) garante que quaisquer linhas horizontais ou verticais na imagem original permaneçam retas na imagem final. Ou seja, ela pegará um retângulo ortogonalmente alinhado e o transformará no quadrilátero especificado, de modo que cada um dos lados do retângulo original permaneça reto com escala constante ao longo de toda a linha. É este aspecto da distorção que torna uma distorção 'BilinearForward' útil em distorções de 'grade' muito mais complexas. Isto é, porque dois 'quadriláteros' vizinhos, mesmo que possam estar distorcidos de forma muito diferente, ainda se alinharão corretamente borda a borda. Aqui está outra comparação entre '[Perspective](#perspective)' e '[BilinearForward](#bilinear_forward)', usando uma distorção muito severa da imagem embutida da rosa...

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Perspective "0,0,3,0 0,46,10,46 70,0,70,7 70,46,60,40" \
          perspective_rose.png
  magick rose: -alpha set -virtual-pixel transparent -interpolate Spline \
          -distort BilinearForward "0,0,3,0 0,46,10,46 70,0,70,7 70,46,60,40" \
          bilinear_rose.png

[IM Output]
Original | | [IM Output]
Perspective | [IM Output]
Bilinear
---|---|---|---

Para atingir seus objetivos (preservar todas as linhas retas), a Distorção Perspective parece 'sugar' quase toda a imagem para a área menor à direita, enquanto a distorção Bilinear manteve a rosa centralizada, centralizada em seus resultados. Novamente, ela preservou as razões de distância, mantendo a rosa igualmente espaçada entre as bordas esquerda e direita. Tudo o que fez foi simplesmente comprimir verticalmente a altura da imagem de forma linear ao longo de seu comprimento. Este aspecto de uma distorção 'BilinearForward' faz com que ela também seja conhecida como distorção 'Trapezoidal'. Isto é, simplesmente comprimir a imagem linearmente em uma direção, quando apenas uma direção é escalada. Essa direção de compressão pode até ser angulada, em vez de alinhada ao longo de um eixo. | _Observe que, devido à complexidade do mapeamento reverso de pixels necessário para realizar uma distorção 'BilinearForward', a Reamostragem por Área está atualmente desativada.

Como tal, áreas de compressão extrema (mais de um fator de 2) provavelmente mostrarão alguns efeitos de aliasing (veja as bordas das linhas nos exemplos acima). No entanto, o uso de Superamostragem ou '-interpolate Spline' pode ser usado para melhorar a qualidade da imagem final.
---|---
| _Antes do IM v6.5.7-0, a distorção 'BilinearForward' ainda estava em desenvolvimento e tinha problemas com casos 'degenerados' específicos, que podiam causar uma imagem de erro 'preta' em situações específicas.

---|---

Distorção Bilinear Reversa

Como apenas as linhas horizontais e verticais permanecem retas, você não pode usar uma distorção 'BilinearForward para reverter a distorção. Como as linhas da grade na imagem transformada não são mais horizontais ou verticais, elas não permanecerão mais retas na imagem resultante! Por exemplo, trocar os pares de coordenadas e reaplicar a distorção 'direta' (como fizemos usando a distorção '[Perspective](#perspective)' acima) não conseguirá recuperar a imagem original.

  magick mandrill_blin.jpg -alpha set -virtual-pixel black \
       -distort BilinearForward \
              '26,0 0,0   114,23 128,0   128,100 128,128  0,123 0,128' \
       mandrill_blin_back.jpg

[IM Output] [IM Output]

Observe que as coordenadas realmente especificadas de fato se posicionaram corretamente, mas a distorção da imagem não foi revertida. Em resumo, uma distorção '[BilinearForward](#bilinear_forward)' NÃO é a sua própria reversa. Para restaurar a imagem, você precisa usar uma distorção ligeiramente diferente, mas intimamente relacionada. A reversa matemática da 'transformação geométrica' foi implementada como uma distorção 'BilinearReverse'. Por exemplo...

  magick mandrill_blin.jpg -alpha set -virtual-pixel black \
       -distort BilinearReverse \
              '26,0 0,0   114,23 128,0   128,100 128,128  0,123 0,128' \
       mandrill_blin_rev.jpg

[IM Output] [IM Output]

| Como afirmado anteriormente, devido à complexidade de uma distorção '[BilinearForward](#bilinear_forward)', a Reamostragem por Área está atualmente desativada, o que no exemplo acima causa graves efeitos de aliasing.
---|---
A '[BilinearReverse](#bilinear_reverse)' tem as mesmas características de preservação de razão de distância de uma 'BilinearFoward', mas mapeará qualquer quadrilátero em um retângulo ortogonalmente alinhado, garantindo que os lados do quadrilátero permaneçam retos quando mapeados para um alinhamento vertical e horizontal. Como você pode ver acima. | Antes do IM v6.5.1-2, a distorção 'BilinearReverse' era implementada simplesmente como 'Bilinear'.
---|---
Algumas implementações de uma distorção bilinear (incluindo versões mais antigas do IM e a Biblioteca Leptonica) implementaram apenas a versão mais simples (reversa) da distorção Bilinear apresentada acima. No entanto, tal distorção não é muito adequada para o 'mapeamento direto' de uma imagem retangular. Por exemplo, aqui tento usar uma '[BilinearReverse](#bilinear_reverse)' para uma distorção que provavelmente deveria ter usado uma distorção '[BilinearForward](#bilinear_forward)'.

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort BilinearReverse \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_blin_rev2.jpg

[IM Output] [IM Output]

Como você pode ver, como o quadrilátero de destino não era um retângulo ortogonal, a imagem foi severamente distorcida, produzindo muitas linhas curvando-se para dentro.

Distorções Bilineares em Mosaico

Agora, embora uma '[BilinearReverse](#bilinear_reverse)' produza imagens 'curvadas' a partir de imagens retangulares. O efeito de fato produz padrões de mosaico interessantes que parecem gerar superfícies curvas de aparência tridimensional. Por exemplo, aplicando a mesma transformação que foi usada para Visualizar Horizontes Distantes acima, obtemos este resultado interessante. |

  magick checks.png  -virtual-pixel tile  -mattecolor DodgerBlue \
          -distort BilinearReverse \
               '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          bilinear_rev_tile.png

[IM Output]
Na verdade, uma '[BilinearReverse](#bilinear_reverse)' nunca produzirá um 'horizonte' (pixels inválidos). Por outro lado, o uso de '[BilinearForward](#bilinear_forward)' tende a produzir 'céu' ou 'pixels inválidos' (preenchidos com o atual "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)") com bastante frequência. De fato, o padrão de mosaico tende a ficar bastante caótico... |

  magick checks.png  -virtual-pixel tile  -mattecolor DodgerBlue \
          -interpolate Spline  -distort BilinearForward \
               '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          bilinear_fwd_tile.png

[IM Output]
| Como afirmado anteriormente, devido à complexidade de uma distorção '[BilinearForward](#bilinear_forward)', a Reamostragem por Área está atualmente desativada, o que no exemplo acima causa graves efeitos de aliasing.
---|---
Como tal, não recomendo o uso de uma forma em mosaico de '[BilinearForward](#bilinear_forward)'. No entanto, recomendo que você defina uma "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" apropriada ao usar a distorção direta, para evitar o surgimento de manchas cinzas inesperadas de 'céu'.

Detalhes Internos da Bilinear

A fórmula real para mapear uma coordenada na imagem de origem para uma imagem de destino usando uma 'Distorção Bilinear com Mapeamento Direto é... Xd = C0*Xs + C1*Ys + C2*Xs*Ys + C3 , Yd = C4*Xs + C5*Ys + C6*Xs*Ys + C7
No entanto, como o IM implementa distorções usando a técnica de Mapeamento Reverso de Pixels, a fórmula acima precisa ser revertida. Um processo complexo que requer a resolução de uma equação quadrática, raízes quadradas e uma página inteira de álgebra. Se você pedir ao IM para gerar de forma Verbosa o equivalente em FX, verá essa complexidade. Por exemplo, usando a imagem checks que criamos anteriormente...
  magick checks.png -alpha set -virtual-pixel transparent -mattecolor none \
      -interpolate Spline -verbose -distort BilinearForward \
                   '0,0,0,0  0,90,0,90  90,0,60,30  90,90,90,90' \
      +verbose bilinear_checks.png

[IM Output]
| [IM Text]


A verificação '(rt > 0 ) ? red :' na linha final do 'equivalente em FX ' serve para evitar uma raiz quadrada negativa inválida. Esta é a verificação que cria o efeito de 'céu' que foi mostrado nos exemplos anteriores. Por outro lado, como a Distorção Bilinear Reversa é muito mais simples, você pode aplicar diretamente a equação polinomial mais simples, para reverter a distorção anterior... |

  magick bilinear_checks.png  -virtual-pixel transparent \
      -verbose -distort BilinearReverse \
                   '0,0,0,0  0,90,0,90  60,30,90,0  90,90,90,90' \
      +verbose bilinear_checks_rev.png

[IM Output]
| [IM Text]


Como você pode ver, as equações resultantes são muito simples, pois agora estamos aplicando-as para fazer um Mapeamento Reverso de Pixels das coordenadas de destino para as coordenadas da imagem de origem. Os efeitos de aliasing vistos acima estão sendo causados pela '[BilinearForward](#bilinear_forward)', e não pela distorção '[BilinearReverse](#bilinear_reverse)'. Isso ocorre porque atualmente a Reamostragem por Área está desativada para a versão de mapeamento 'direto' devido à sua complexidade.
Para leitura adicional, direciono você a Transformações Afim e Perspectiva da Leptonica.

Distorção Bilinear Combinada

Em Construção

Os dois métodos de Distorção Bilinear juntos permitirão que você distorça diretamente QUALQUER quadrilátero em qualquer outro quadrilátero, mantendo os lados do quadrilátero retos. Essencialmente, você pode primeiro fazer uma distorção 'Reversa' de um quadrilátero em uma imagem retangular, e então pode fazer uma distorção 'Direta' desse retângulo no quadrilátero final. Este tipo de distorção também significa que você pode pegar qualquer grade retangular de coordenadas e distorcê-las para outra grade retangular de coordenadas. Isso é conhecido como distorção de 'Grade'. Esta técnica é a principal base do Morphing de Imagem, onde você define uma grade retangular de linhas sobre duas imagens e as usa para mesclar as imagens em um composto intermediário, ou até mesmo gerar uma animação que faz o morphing adequadamente de uma imagem para outra. Isso, no entanto, ainda não foi implementado, embora seja uma adição planejada.


Distorção Polynomial (distorce usando um ajuste polinomial)

A distorção 'Polynomial', como a maioria dos métodos de distorção anteriores, também mapeia pares de pontos de controle, mas usa uma equação polinomial padrão. Isso significa que um argumento extra é necessário antes de os pontos de controle serem fornecidos.

Order X1,Y1 I1,J1 X2,Y2 I2,J2 X3,Y3 I3,J3 X4,Y4 I4,J4 . . . .

O argumento 'Order ' é geralmente um inteiro a partir de '1', embora um valor especial de '1.5' também possa ser usado. Isso define a 'ordem' ou complexidade da equação matemática bidimensional (usando tanto 'x' quanto 'y') que será aplicada. Por exemplo, um polinômio de ordem '1' ajustará uma equação da forma... Xd = | C2x*Xs + C1x*Ys + C0x | , | Yd = | C2y*Xs + C1y*Ys + C0y |
---|---|---|---|---|---
Que, se você comparar com a equação usada para Projeção Afim, verá que é o equivalente. Como 3 constantes são necessárias para cada fórmula X e Y, você também precisa fornecer pelo menos 3 pares de coordenadas X,Y. Qualquer quantidade a mais fará com que a equação seja ajustada por mínimos quadrados às coordenadas fornecidas. A próxima 'ordem', '1.5', é equivalente a uma '[BilinearReverse](#bilinear_reverse)' (lembre-se de que a equação é usada para mapear as coordenadas de destino para a imagem de origem). Xd = | C3x*Xs*Ys + C2x*Xs + C1x*Ys + C0x | , | Yd = | C3x*Xs*Ys + C2y*Xs + C1y*Ys + C0y |
---|---|---|---|---|---
Assim como a distorção '[BilinearReverse](#bilinear_reverse)', ela precisa de um mínimo de 4 coordenadas. Por exemplo... Basicamente, isso é exatamente igual às equações de ordem '1', mas com 1 termo extra adicionado às equações polinomiais. Ou seja, como cada equação agora tem 4 termos por eixo, com 4 constantes, você agora precisa de pelo menos 4 pares de coordenadas para permitir que o IM determine essas constantes.

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort Polynomial \
              '1.5   0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_poly_1.5.jpg

[IM Output] [IM Output]

Com uma ordem '2', as equações polinomiais são expandidas ainda mais para se tornarem um ajuste quadrático completo, exigindo um mínimo de pelo menos 6 pares de coordenadas. Xd = C5x*Xs2 + C4x*Xs*Ys + C3x*Ys2 + C2x*Xs + C1x*Ys + C0x
Yd = C5y*Xs2 + C4y*Xs*Ys + C3y*Ys2 + C2y*Xs + C1y*Ys + C0y
Basicamente, isso é exatamente igual às equações de ordem '1', mas com 3 termos extras (ordem 2 + 1) pré-anexados às equações polinomiais. Ou seja, como cada equação agora tem 6 termos com 6 constantes, você agora precisa de pelo menos 6 coordenadas para permitir que o IM determine essas constantes. Cada ordem sucessiva de polinômio após esta adiciona outros 'order'+1 termos a cada par de equações. Como tal, um polinômio de ajuste cúbico de ordem '3' requer um mínimo de 10 pares de coordenadas para ser totalmente definido, e um polinômio de ajuste quíntico de ordem '4' precisa de 15 pares de coordenadas. Você pode usar um Resumo de Distorção Verboso para ver a equação resultante que a distorção polinomial ajustou às coordenadas especificadas. Como um exemplo maior, tenho uma imagem de uma grade. Também tenho um grande conjunto de coordenadas (armazenadas no arquivo "[grid16_control_points.txt](../static/img/images/grid16_control_points.txt)") sobre como quero deformar essa grade. Em seguida, pedi ao IM para gerar um polinômio cúbico para o 'melhor ajuste' das coordenadas de entrada.
  # warp image
  magick grid16.png -virtual-pixel gray \
          -distort polynomial "3 $(cat grid16_control_points.txt)" \
          grid16_polynomial.png

  # reverse image coordinate order
  awk '{print $3, $4, $1, $2}' grid16_control_points.txt \
                             > grid16_cp_inverse.txt

  # warp image back again
  magick grid16_polynomial.png -virtual-pixel gray \
          -distort polynomial "3 $(cat grid16_cp_inverse.txt)" \
          grid16_restored.png

[IM Output] [IM Output] [IM Output]

O pequeno script "awk" pega o conjunto original de pares de pontos de controle X,Y e inverte a ordem, para que possamos então usar o novo arquivo para tentar 'desfazer' a distorção. | _As coordenadas no arquivo de pontos de controle "[grid16_control_points.txt](../static/img/images/grid16_control_points.txt)" estão em coordenadas de imagem, ou seja, cada número se refere ao centro do pixel a que se refere. Sem o 0,5 adicional, os valores estariam em 'coordenadas de pixel' inteiras. Veja Coordenadas de Imagem vs Coordenadas de Pixel acima.

Os valores foram determinados puramente por busca manual usando um visualizador de imagens e, como tal, não são realmente muito exatos. Isso pode ser a origem de alguns dos artefatos de distorção reversa, embora o 'melhor ajuste' funcional das equações polinomiais teria reduzido os efeitos gerais de distorção.


---|---
Isso mostra que, embora uma distorção polinomial funcione, e funcione bem, ela não é uma distorção exata ou reversível. Essencialmente, as 81 coordenadas são 'promediadas' juntas de modo a gerar um 'melhor ajuste' matemático das coordenadas de entrada. Como mais pontos de controle (81) foram fornecidos em vez do mínimo (10) necessário, nenhum dos pontos de controle tem garantia de corresponder exatamente às coordenadas solicitadas. No entanto, para este exemplo específico, onde as coordenadas estão próximas do resultado distorcido esperado, deve estar razoavelmente próximo. A função polinomial geralmente terá mais erros ao longo das bordas e especialmente nos cantos da imagem. Isso não afeta apenas as localizações dos pixels, mas também a área de amostragem (EWA) nas bordas. Este é um resultado natural da aproximação usada. Um polinômio de ordem mais alta poderia ter sido usado, mas neste caso não faz grandes melhorias. Para este caso específico, o polinômio está na verdade tentando ajustar-se a uma função trigonométrica não polinomial. Devido à natureza dessas funções, a segunda distorção será mais imprecisa do que a primeira. Este exemplo está, na verdade, muito intimamente relacionado a um método radial de Distorção de Barril que veremos abaixo. Observe, no entanto, que as coordenadas sendo mapeadas não precisam realmente estar em um arranjo de grade, mas podem ser qualquer conjunto de mapeamento de coordenadas. Por causa disso, é frequentemente usado por geógrafos para alinhar (e sobrepor) fotos aéreas com mapas geofísicos, usando localizações conhecidas de cidades, cruzamentos, picos de montanhas e outros pontos de referência como pontos de controle. | _Devido ao fato de a Distorção Polynomial ser geralmente não reversível, não é possível para o IM calcular o 'melhor ajuste' da viewport da imagem de destino, para a imagem de origem fornecida. Como tal, a forma "[+distort](#distort_bestfit)" do operador não funciona, e recorre a uma operação normal "[-distort](https://imagemagick.org/command-line-options/#distort)". No entanto, você ainda pode usar a opção Viewport de Distorção para definir a viewport da imagem de destino.

---|---


Métodos de Distorção Circular e Radial

Estas são distorções que envolvem o uso de vetores radiais como o principal componente do processo de distorção.

Distorção Arc (curvando imagens em arcos circulares)

A distorção 'Arc' (a partir do IM v6.3.5-5) é uma variação simples de uma distorção polar muito mais complexa (veja abaixo). Por padrão, ela curvará a imagem dada em um arco perfeitamente circular sobre o ângulo fornecido, e sem outros argumentos tentará preservar tanto a escala da linha central horizontal da imagem quanto a proporção da imagem, o máximo possível. Para isso ela recebe até quatro argumentos.

_arc_angle rotate_angle top_radius bottom_radius_

No entanto, apenas o "_arc_angle_" é obrigatório, os outros argumentos são opcionais e podem ser adicionados conforme necessário, na sequência dada. Por exemplo, 'Arc' uma imagem sobre um ângulo de 60 graus... |

  magick rose: -virtual-pixel White -distort Arc 60  arc_rose.jpg

[IM Output]
| _Observe que, ao contrário dos outros operadores de distorção de imagem, uma distorção 'Arc' sempre definirá o tamanho da imagem resultante de modo que a imagem de origem completa esteja presente. Isso inclui quaisquer pixels de borda de anti-aliasing. Como tal, a imagem resultante raramente corresponderá ao tamanho da imagem de entrada.

Apenas as Opções de Distorção Viewport permitirão que você altere o tamanho da imagem resultante para uma distorção específica._
---|---
Adicionar o segundo argumento "_rotate_agle_" permite que você rotacione a imagem ao redor do círculo. Por exemplo, rotacioná-la em 90 graus. |

  magick rose: -virtual-pixel White -distort Arc '60 90'  arc_rose_rot.jpg

[IM Output]
Como nenhum argumento de raio específico foi mencionado, o método de distorção 'Arc' faz grande esforço para tentar garantir que a escala da imagem original seja preservada o máximo possível. Para isso, a linha central horizontal da imagem é definida como o 'raio ideal' para a largura e o "_arc_angle_" dado da imagem de origem. Isso significa que, se você arqueia a imagem sobre um "_arc_angle_" maior, o raio da linha central usado também encolherá pelo mesmo fator. Como tal, o raio da linha central será menor e mais apertado. |

  magick rose: -virtual-pixel White -distort Arc 120  arc_rose_3.jpg

[IM Output]
Observe como a imagem agora se ajustará a um círculo menor, mas que a borda inferior da imagem é um círculo ainda menor! Se você definir um ângulo ainda maior sobre o qual arquear a imagem, a borda inferior atingirá o centro da distorção, e além, o que resulta na parte inferior da imagem de origem desaparecendo no esquecimento.

  magick rose: -virtual-pixel White -distort Arc 60   arc_rose_1.jpg
  magick rose: -virtual-pixel White -distort Arc 90   arc_rose_2.jpg
  magick rose: -virtual-pixel White -distort Arc 120  arc_rose_3.jpg
  magick rose: -virtual-pixel White -distort Arc 180  arc_rose_4.jpg
  magick rose: -virtual-pixel White -distort Arc 240  arc_rose_5.jpg
  magick rose: -virtual-pixel White -distort Arc 300  arc_rose_6.jpg
  magick rose: -virtual-pixel White -distort Arc 360  arc_rose_7.jpg

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

Arc em Anéis de Círculo Completo

Imagens mais longas se distorcerão com 'Arc' muito melhor sobre ângulos muito grandes. Por exemplo, você pode envolver imagens longas (como mensagens de texto) em anéis. E só para que você possa realmente ver o que está acontecendo aqui, defini uma cor de fundo de Pixel Virtual diferente, para que você possa ver o limite da imagem original.

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 60     arc_circle_1.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 120    arc_circle_2.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 180    arc_circle_3.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 270    arc_circle_4.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 360    arc_circle_5.jpg

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

E pronto, 'arqueamos' a imagem do rótulo em um círculo completo. Se você olhar de perto a junção da imagem do círculo completo, poderá ver uma pequena linha de pixels, onde a junção não está totalmente completa. Isso é causado pelo efeito do fundo de Pixel Virtual 'SkyBlue' circundante, pois estamos efetivamente unindo duas bordas de uma imagem. Ao gerar um círculo completo, você precisa usar um método de pixel virtual que 'una' essas duas bordas corretamente. Isso geralmente é feito usando um dos métodos de Pixel Virtual de ladrilhamento, como o Tile. |

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Tile -background SkyBlue \
          -distort Arc 360   arc_circle_tile.jpg

[IM Output]
Infelizmente, como você pode ver, isso não apenas une a imagem corretamente, mas também gera linhas duplicadas da imagem entrando e saindo do anel primário. Não é bom. A partir do IM v6.4.2-6 um novo método de Pixel Virtual, HorizontalTile, resolve esse problema. Esse método ladrilha a imagem apenas lateralmente, então cria uma boa junção para nossa imagem em círculo, mas preenche as áreas acima e abaixo dos ladrilhos com a cor de fundo atual, produzindo um círculo perfeito de texto. |

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc 360   arc_circle.jpg

[IM Output]
Se antes de 'arquear' uma imagem você rotacionar a imagem de entrada de cabeça para baixo, poderá colocar o 'topo' original da imagem na borda interna do círculo. Claro que você pode querer 'rotacionar' o resultado de volta para cima novamente depois, mas essa capacidade já está incorporada ao método de distorção 'Arc'. |

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background -background SkyBlue \
          -rotate 180 -distort Arc '270 180'  arc_flip.jpg

[IM Output]
O terceiro argumento "_top_radius_" substituirá o raio 'ideal' da linha central que é calculado, de modo que o topo da imagem se tornará um círculo do raio dado. Isso cria um anel de 100 pixels de largura, embora a imagem que o acomoda tenha 102 pixels de largura para permitir efeitos de anti-aliasing. |

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc '360 0 50'  arc_radius.jpg

[IM Output]
A imagem ainda mantém a mesma proporção, então o acima é essencialmente o mesmo de antes, apenas escalado de modo a ajustar-se ao círculo do raio solicitado. Lembre-se de que o raio pode ser de ponto flutuante, mas o centro de um arco sempre será alinhado a um 'canto' de pixel, então a imagem resultante ainda terá um número par de pixels de largura. Se você fornecer o quarto argumento "_bottom_radius_", pode obter controle completo da largura do anel, ou de sua 'altura radial'. |

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc '360 0 45 30'   arc_inner.jpg

[IM Output]
Isso distorcerá a escala radial da imagem e efetivamente separa a escala radial da 'largura do arco' ou ângulo da imagem resultante. Em outras palavras, a proporção original da imagem não será mais preservada. Você pode até forçá-la a preencher completamente o interior do círculo, envolvendo a borda inferior da imagem de entrada no centro, ou 'polo' da distorção. |

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc '360 0 45 0'   arc_fill.jpg

[IM Output]

Exemplos de Distorção Arc

Você pode gerar efeitos interessantes usando uma Distorção Arc, por exemplo, arqueando um padrão de tabuleiro de xadrez alongado no anel (usando a configuração de Pixel Virtual '[HorizontalTile](misc.html#horizontal_tile)' produz... |

  magick -size 210x30 pattern:checkerboard -alpha set \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc 360   arc_checks.png

[IM Output]
Ao usar a configuração padrão de Pixel Virtual '[Edge](misc.html#edge)', você pode produzir um efeito mais interessante. |

  magick -size 210x30 pattern:checkerboard  -virtual-pixel Edge \
          -distort Arc 360   arc_checks_edge.png

[IM Output]
Claro que uma configuração '[Tile](misc.html#edge)' também gerou efeitos 'radiais' interessantes, permitindo que você gere um padrão de tabuleiro de xadrez circular. |

  magick -size 210x30 pattern:checkerboard  -virtual-pixel Tile \
          -distort Arc 360   arc_checks_tile.png

[IM Output]
O acima pode ser refinado ainda mais controlando o raio superior e inferior da imagem resultante. Aqui estão mais alguns exemplos de distorção '[Arc](#arc)', mas deixo que você brinque com eles para descobrir como funcionam. O que você consegue criar? |

  magick -size 90x1 pattern:gray50 -scale 900x100 -normalize \
          -virtual-pixel Tile  -set option:distort:viewport 100x100-50-50 \
          -distort Arc 360  +repage  arc_radii.gif

[IM Output]
|

  magick -size 400x100 pattern:hs_diagcross \
          -virtual-pixel Tile  -set option:distort:viewport 100x100-50-50 \
          -distort Arc '360 0 80 0' +repage  arc_cross.gif

[IM Output]
|

  magick -size 360x80 xc: -draw "fill none stroke black line 0,5 360,80" \
          -virtual-pixel White  -distort Arc '360 0 50 0'  arc_spiral.gif

[IM Output]

|

  magick tree.gif -set option:distort:viewport 120x60-60-60 \
          -virtual-pixel Dither  +distort Arc '180 0 25 0' \
          +repage arc_rays.gif

[IM Output]
Os 'raios' neste último exemplo são um subproduto da configuração de Pixel Virtual pseudoaleatória '[Dither](misc.html#dither)', resultando em um padrão de pixels estranho da cor do 'sol' vinda do canto superior esquerdo da imagem original. Os mesmos efeitos de pontilhamento também produzem a linha circular de 'traços' ao redor da imagem da 'árvore'. Você pode obter uma versão semelhante e mais controlada desse efeito usando uma configuração '[Edge](misc.html#edge)' com uma imagem que tenha sido modificada para adicionar pixels de borda interessantes.

Posicionamento do Ponto Central do Arc

Por padrão, '[Arc](#arc)' ignorará completamente qualquer deslocamento de Tela Virtual que a imagem possa ter, ou nem mesmo relatará a localização do 'centro' ao redor do qual a imagem foi arqueada. No entanto, conhecer a localização do 'ponto central' pode ser muito útil. Se em vez de usar "-distort" você usar a forma especial com sinal de mais, "+distort", a imagem receberá uma Tela Virtual, de modo que o centro esteja localizado na origem da tela virtual. Em outras palavras, o ponto '0,0' da imagem é definido como o 'centro' do arco. Isso é especialmente útil para posicionar uma imagem arqueada com um ângulo menor que o círculo completo, onde o 'centro' do arco não é o centro da imagem. Para um exemplo... |

  magick logo: -resize x150 -gravity NorthEast -crop 100x100+10+0! \
          \( -background none label:'IM Examples' \
             -virtual-pixel Background +distort Arc '270 50 20' \
             -repage +75+21\! \)  -flatten  arc_overlay.jpg

[IM Output]
Aqui eu crio um rótulo de texto e o distorci com '[Arc](#arc)' em um círculo incompleto usando a forma com sinal de mais "+distort" do operador. O 'centro' do arco foi cuidadosamente preservado pelo IM usando o deslocamento de tela virtual das imagens. Isso significa que, simplesmente fazendo um ajuste relativo do deslocamento usando "-repage" com um sinalizador '!', podemos posicionar o círculo de texto resultante em qualquer lugar que quisermos! Como a ponta do chapéu do mago, que está localizada nas coordenadas de pixel 75,21, no exemplo acima. Infelizmente, como deslocamentos virtuais são usados para posicionar a imagem, o posicionamento exato é limitado a tamanhos de pixel inteiros. Você não pode posicionar uma Distorção Arc em uma localização definida em subpixel sem fazer uma segunda distorção. No entanto, você pode fazer isso para uma Distorção Polar (veja a seguir).

Distorção Polar (distorce em círculo completo)

A distorção 'Polar' (adicionada no IM v6.4.2-6) é uma versão mais de baixo nível da distorção '[Arc](#arc)' acima. Mas ela não faz 'bestfit' automaticamente, nem tenta preservar as proporções das imagens. Os 6 argumentos opcionais de ponto flutuante são... Radius_Max Radius_Min Center_X,Center_Y Start_Angle,End_Angle

Todos os argumentos são opcionais nas posições espaçadas. Por padrão, o 'CenterX,Y ' assume por padrão o exato centro da área da imagem de entrada. Então uma imagem polar de círculo completo será gerada de modo que toda a borda superior se torne o centro, enquanto a borda inferior é envolvida completamente ao redor do exterior do círculo. As bordas esquerda e direita se encontrarão acima do ponto central em ângulos de '-180' a '+180' da imagem. Como o 'Radius_Max ' deve ser fornecido, ele deve ter algum valor positivo. No entanto, se você fornecer um valor de '0', ele será definido como a distância entre o centro e a borda mais próxima, de modo que, se os outros valores não forem fornecidos (padrões), toda a imagem de entrada é mapeada em um círculo no meio da imagem. Por exemplo, vamos aplicar magick a um mapa-múndi em uma visão polar, usando todos os padrões. É claro que você deve especificar uma configuração de Pixel Virtual de '[HorizontalTile](misc.html#horizontal_tile)' ao produzir um mapeamento polar de círculo completo...

  magick worldmap_sm.jpg -virtual-pixel HorizontalTile  \
          -background Black   -distort Polar 0   polar_arctic.jpg

[IM Output] [IM Output]

É claro que isso distorce severamente o hemisfério sul, envolvendo a Antártida completamente ao redor da circunferência do 'diskworld'. Ao rotacionar a imagem de origem e recortá-la de modo a mostrar apenas a calota polar, podemos gerar um bom mapa do Continente Antártico. Também especifiquei um raio de saída maior, para torná-lo mais visível, e pedi ao IM para 'ajustar' a imagem de saída a esse tamanho usando a forma 'plus' do Operador Distort. |

  magick worldmap_md.jpg -rotate 180 -crop 100%x25%+0+0 +repage \
          -virtual-pixel HorizontalTile -background Black \
          +distort Polar 80 +repage  polar_antarctica.jpg

[IM Output]
Observe que as imagens acima não são visões estritamente corretas da Terra, pois o mapa cartesiano é uma representação de uma esfera, e não uma imagem em coordenadas polares. Se você usar um valor especial de 'Radius_Max ' de exatamente '-1', o raio da imagem distorcida é definido como a distância do centro até o canto mais distante (diagonal). Isso serve para fornecer um 'reverso' ideal para uma distorção '[DePolar](#depolar)' de imagem completa, que veremos a seguir. (Veja Truques (De)Polar abaixo para exemplos de uso). | Lembre-se de que, ao contrário de uma distorção '[Arc](#arc)', a distorção '[Polar](#polar)' (também conhecida como distorção 'Cartesiana para Polar') não faz nenhuma tentativa de preservar a proporção 'ideal' da imagem de origem. Recomenda-se cautela.
---|---
Os argumentos 'CenterX,Y ' são mais úteis para posicionar o centro da imagem resultante em um deslocamento de subpixel. Ou seja, se o centro está na fronteira de um pixel (número inteiro) ou no centro de um pixel (com deslocamentos de 0,5). É claro que ele também determina a localização da 'camada' da tela virtual. Por padrão, porém, é atribuído um valor no meio da imagem (para "-distort", que usa a imagem de entrada como viewport) ou 0,0 (para a imagem de camada de "+distort"). Os próximos argumentos 'Start_Angle,End_Angle são ainda menos comumente usados, e limitam os ângulos que a imagem de entrada cobre, assumindo por padrão um valor de -180 a 180 graus (0 é para baixo em linha reta). Como na distorção '[Arc](#arc)', você poderia usar isso para rotacionar a imagem polar resultante. Mas também pode ser usado para gerar 'arcos'. Por exemplo...

  magick worldmap_sm.jpg -virtual-pixel Black -background Black \
          +distort Polar  '60,20 0,0 -60,60' +repage  polar_arc.jpg

[IM Output] [IM Output]

Observe que atualmente o IM não reduz o tamanho da imagem de camada resultante, que é alinhada de modo que a origem das imagens virtuais fique nas coordenadas 0,0, conforme solicitado. Além do estilo de argumento, esta é a maior diferença entre as distorções '[Arc](#arc)' e '[Polar](#polar)'. Observe também que a borda esquerda (ângulo -60) fica à esquerda. Isso é matematicamente correto quando você considera que o eixo 'Y' é para baixo (o mesmo que para todas as rotações de imagem). É claro que, como no Arc, você pode usar efeitos de ladrilhamento de Pixel Virtual para gerar padrões repetidos. Por exemplo, este é exatamente igual ao último exemplo, apenas com uma configuração '[HorizontalTileEdge](misc.html#horizontal_tile)'... |

  magick worldmap_sm.jpg -virtual-pixel HorizontalTile -background Black \
          +distort Polar  '60,20 0,0 -60,60' +repage  polar_arc_tiled.jpg

[IM Output]

Distorção DePolar (Polar para Cartesiana)

Esta é essencialmente a inversa de uma distorção '[Polar](#polar)', e tem exatamente o mesmo conjunto de argumentos opcionais. Os 6 argumentos opcionais de ponto flutuante são...

Radius_Max Radius_Min Center_X,Center_Y Start_Angle,End_Angle

Novamente, se o 'Radius_Max ' for definido como '0', a distância do 'CenterX,Y ' até a borda mais próxima é usada, o que significa que qualquer coisa no maior círculo completo será mapeada para caber em uma imagem do mesmo tamanho da imagem de entrada. Por exemplo, vamos reverter o 'diskworld' anterior de volta para um Mapa Cartesiano.

  magick polar_arctic.jpg  -distort DePolar 0  world_restored.jpg

[IM Output] [IM Output]

Como o tamanho da imagem de entrada foi preservado ao longo de todas as duas distorções, o resultado acima é basicamente exatamente igual ao mapa original. É claro que, como a imagem foi comprimida tanto no 'polo' superior quanto no raio, a saída é bem mais borrada do que você poderia esperar. Na verdade, é agravado pelo fato de que o algoritmo deReamostragem de Área (EWA) não consegue amostrar pixels em um arco circular. Por isso, a Reamostragem de Área é desativada para as distorções "[DePolar](#depolar)". Recomenda-se que alguma forma de técnica de Super-Amostragem seja usada em vez disso, como mostrado na próxima seção.
Se você permitir que o IM use 'bestfit' (usando a forma "+distort" do operador), então ele redimensionará a imagem de saída de modo a manter o 'Radius_Max ' em escala unitária, e definirá a largura como a distância da circunferência do raio a meio caminho entre 'Radius_Max ' e 'Radius_Min '. Isso essencialmente tenta preservar da melhor forma a Proporção da imagem polar, embora isso possa produzir uma imagem mais longa e fina do que o esperado. Por exemplo.
  magick polar_arctic.jpg  +distort DePolar 0  world_restored_2.jpg

[IM Output] [IM Output]

Truques de Ciclo (De)Polar (borrões radiais/angulares)

Como vimos acima, usar um 'Radius_Max ' de '0' garantirá que toda a imagem seja mapeada em um círculo ao usar uma distorção '[Polar](#polar)' (Cartesiana para Polar), e a mesma configuração mapeará esse círculo de volta em uma imagem retangular usando '[DePolar](#depolar)' (Polar para Cartesiana). No entanto, isso não funcionará muito bem se você quiser aplicar '[DePolar](#depolar)' a uma imagem retangular e depois reverter a distorção novamente usando '[Polar](#polar)'. Por exemplo, vamos pegar uma imagem de flor, aplicar de-polar e depois restaurá-la usando o valor especial de 'Radius_Max ' de '0' (raio = borda mais próxima).

  magick flower_sm.jpg -virtual-pixel Black \
          -distort DePolar 0  flower_depolar.jpg
  magick flower_depolar.jpg \
          -virtual-pixel HorizontalTile -background black \
          -distort  Polar  0  flower_circle.jpg

[IM Output] [IM Output] [IM Output]

Agora a imagem não é restaurada corretamente, pois foi cortada pela primeira distorção '[DePolar](#depolar)'. Ainda assim, esta é uma técnica útil por si só, e pode ser usada para gerar máscaras circulares perfeitas para uma imagem existente, dimensionada de uma forma completamente independente da imagem de entrada fornecida. Para fazer essa técnica de ciclo '[DePolar](#depolar)'-'[Polar](#polar)' corretamente, precisamos usar um raio que seja a distância do centro até o canto mais distante. O valor especial de 'Radius_Max ' de '-1' pedirá ao IM para calcular e usar o canto mais distante do 'ponto central' como o raio.

  magick flower_sm.jpg  -virtual-pixel Black \
          -distort DePolar -1  flower_depolar-1.jpg
  magick flower_depolar-1.jpg \
          -virtual-pixel HorizontalTile -background black \
          -distort  Polar  -1  flower_restored.jpg

[IM Output] [IM Output] [IM Output]

A imagem restaurada fica ligeiramente borrada, o que é causado pela compressão do raio necessária para preservar toda a imagem durante a operação '[DePolar](#depolar)'. Isso, no entanto, pode ser corrigido usando uma técnica apropriada de Super-Amostragem (veja o próximo conjunto de exemplos). Mas por que você iria querer aplicar magick a uma imagem nessa forma e de volta novamente? Bem, aplicando outras distorções na versão intermediária 'DePolar' da imagem, você pode gerar alguns efeitos radiais ou angulares muito sofisticados com bastante facilidade. Por exemplo, ao rolar a imagem intermediária, você rotacionará a imagem de saída, embora possa obter algum recorte dos cantos... |

  magick flower_sm.jpg -virtual-pixel Black -distort DePolar -1 \
          -roll +15+0 \
          -virtual-pixel HorizontalTile -background Black \
          -distort  Polar  -1  flower_polar_rotate.jpg

[IM Output]
Observe que a direção da rotação é invertida em relação à do Operador Rotate ou da Distorção SRT.

Problemas do Ciclo Depolar-Polar

Na rotação de imagem acima, você pode ter notado algumas distorções tipo 'escada' ao longo da borda da imagem rotacionada. Este é um problema bem conhecido e é causado pela compressão da grande circunferência circular da imagem na 'largura' menor da imagem de entrada. Por exemplo, aqui eu pego a imagem de teste de tabuleiro de xadrez e apenas a executo através de um ciclo Depolar-Polar normal sem fazer nenhuma alteração.

  magick checks.png   -virtual-pixel Transparent \
          -distort DePolar -1   checks_depolar.png
  magick checks_depolar.png  -virtual-pixel HorizontalTile -background None \
          -distort  Polar  -1   checks_cycled.png

[IM Output] [IM Output] [IM Output]

Você pode ver claramente os efeitos de serrilhamento causados pela compressão da imagem nas pontas da imagem intermediária. Isso também é agravado pelo fato de que a Reamostragem de Área normal não é usada durante aquela conversão '[Depolar](#depolar)' inicial da imagem de entrada. A melhor maneira de resolver esse problema é usar o Escalonamento de Saída de Distort para tanto ampliar a imagem intermediária quanto depois reduzir a imagem final. Isso fornecerá um resultado Super-Amostrado, que removerá os artefatos de compressão vistos acima. Por exemplo, este é o melhor ciclo depolar-polar 'sem operação', tudo em um único comando... |

  magick checks.png -virtual-pixel Background -background None \
          -set option:distort:scale 4  -distort DePolar -1 \
          -noop \
          -virtual-pixel HorizontalTile -background None \
          -set option:distort:scale .25 -distort  Polar  -1 \
          checks_cycled_ss.png

[IM Output]
Como você pode ver, os horríveis efeitos de serrilhamento praticamente desapareceram. No entanto, esteja avisado de que uma imagem muito alta e fina poderia fazer o problema reaparecer. A melhor ideia é limitar isso a imagens 'landscape' ou largas, com super-amostragem como mostrado acima. Tudo o que você precisa fazer agora é substituir o operador "-noop" pelo comando apropriado para gerar o efeito radial e rotacional que você procura.

Exemplo de Efeitos Depolar-Polar

Então vamos novamente mostrar uma Rotação Polar melhor da imagem, desta vez usando super-amostragem. Observe, porém, que como a imagem intermediária é 4 vezes maior, a quantidade de Rolagem de Imagem também precisa ser 4 vezes maior. |

  magick flower_sm.jpg   -virtual-pixel Black \
          -set option:distort:scale 4   -distort DePolar -1 \
          -roll +60+0   \
          -virtual-pixel HorizontalTile -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_polar_rotate_ss.jpg

[IM Output]
Como você pode ver, o efeito 'escada' ao longo da borda foi removido, com um resultado de imagem de qualidade muito mais alta.
Ou você pode aplicar um borrão linear simples da imagem intermediária (tal como obtido ao comprimir e ampliar a imagem novamente). |

  magick flower_sm.jpg -virtual-pixel Black \
          -set option:distort:scale 4   -distort DePolar -1 \
          -scale 10%x100%\! -filter Gaussian -resize 1000%x100%\! +filter \
          -virtual-pixel HorizontalTile -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_angular_blur.jpg

[IM Output]
O resultado é muito semelhante a um 'Borrão Rotacional ' da imagem. Isso é parecido, mas não exatamente igual ao mal nomeado Operador Radial Blur. Na verdade, os resultados têm uma qualidade mais alta do que aquele método de borrão especializado. Observe que o uso de uma cor 'black' nas várias formas de Configurações de Pixel Virtual que foram aplicadas resultará em um leve escurecimento das bordas, mas não é tão ruim no caso acima. Um método para remover os efeitos de bordas 'pretas' seria usar a cor 'transparency' em vez disso, e depois simplesmente desligar completamente o canal alfa ao terminar, de modo a deixar apenas a cor real que o IM calculou. Outro é usar dois métodos de pixel virtual de 'borda' ('[Edge](misc.html#edge)' e '[HorizontalTileEdge](misc.html#horizontal_edge)'), que estendem as bordas da imagem para o espaço indefinido da tela virtual. |

  magick flower_sm.jpg -virtual-pixel Edge \
          -set option:distort:scale 4   -distort DePolar -1 \
          -scale 10%x100%\! -filter Gaussian -resize 1000%x100%\! +filter \
          -virtual-pixel HorizontalTileEdge -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_angular_blur_edge.jpg

[IM Output]
O que mostra um resultado muito melhor perto das bordas.
Ao borrar a versão polar da imagem verticalmente, desta vez usando o Operador Motion Blur, em vez da compressão por redimensionamento, você pode gerar Faixas Radiais que se movem para fora a partir do centro da imagem... |

  magick flower_sm.jpg   -virtual-pixel Black \
          -set option:distort:scale 4   -distort DePolar -1 \
          -virtual-pixel Edge   -motion-blur 0x28-90 \
          -virtual-pixel HorizontalTile -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_radial_blur.jpg

[IM Output]
Para fazer com que o resultado borre apenas os realces (as pétalas) da imagem, você pode compor isso com a imagem original usando Lighten, de modo que apenas as cores mais claras borradas permaneçam visíveis, com as cores escuras não borrando nas áreas mais claras e destruindo os pontos amarelos no meio da flor. |

  magick flower_sm.jpg  flower_radial_blur.jpg \
          -compose Lighten -composite   flower_radial_blur_lighten.jpg

[IM Output]
Veja também Estrelas e Cometas para outro exemplo de como fazer isso, mas gerando diretamente a imagem intermediária 'DePolar', antes de aplicar uma distorção '[Polar](#polar)'.Um agradecimento especial vai para Fred Weinhaus pelos usos especiais de um ciclo DePolar-Polar, e por insistir que eu garantisse que essas distorções fossem totalmente reversíveis para imagens retangulares. Ele emprega bem essa técnica em vários de seus Scripts do ImageMagick, incluindo "[bump](http://www.fmwconcepts.com/imagemagick/bump/index.php)", "[ripples](http://www.fmwconcepts.com/imagemagick/ripples/index.php)", e "[striations](http://www.fmwconcepts.com/imagemagick/striations/index.php)".

Distorção Barrel (corrigindo distorções de lente)

A Distorção Barrel (adicionada ao IM v6.4.2-4) foi projetada especificamente para corrigir as distorções esféricas causadas por lentes de câmera em fotos. Ou seja, distorções como os efeitos barrel e pincushion, que são efetivamente o inverso um do outro. Para a aplicação prática deste operador na correção de distorção de lente, veja a seção Correção de Lente. A distorção é implementada com base em um conjunto de 4 valores de coeficiente, conhecidos como A, B, C e D, conforme definido pelo Professor Helmut Dersch, em um site que desde então desapareceu. Você pode ver um arquivo do Wayback Machine do site em Correcting Barrel Distortion. Os valores basicamente formam uma equação de distorção tal que...

_R src_ = r * ( A*_r 3_ + B*_r 2_ + C*_r_ + D )

Onde "_r_" é o raio de destino e "_R src_" é o pixel de origem de onde obter a cor do pixel. Os raios são normalizados de modo que raio = '1.0' para a metade da menor largura ou altura da imagem de entrada. Isso pode parecer invertido, mas é porque a técnica de Mapeamento Reverso de Pixel é usada para garantir a cobertura completa da imagem resultante. Todos os quatro coeficientes (A, B, C e D) são fixos para qualquer combinação específica de câmera, lente e zoom. Todos os três normalmente são armazenados com a imagem em um Perfil EXIF. Isso é importante pois significa que, uma vez que você tenha esses valores para sua câmera, pode usá-los para remover a distorção esférica de lente presente em todas as fotos tiradas por aquela combinação de câmera e lente. Os argumentos necessários para o método de distorção '**Barrel**'. Geralmente você fornece apenas 3 ou 4 valores...

_A B C_ [ _D_ [ _X_ , _Y_ ] ]

Os argumentos opcionais X ,Y fornecem um 'centro' opcional para a distorção radial; caso contrário, o padrão é o centro exato da imagem fornecida (independentemente de seu deslocamento virtual). Os coeficientes são projetados de modo que, se todos os quatro valores A a D somarem '1.0', a largura/altura mínima da imagem não mudará. Por essa razão, se D (que controla o dimensionamento geral da imagem) não for fornecido, ele será definido de modo que todos os quatro valores somem '1.0'. Usar os parâmetros '0.0 0.0 0.0' (equivalente a _A_ =_B_ =_C_ =0.0 e _D_ =1.0') não produzirá nenhuma mudança na imagem de entrada, e é o argumento 'no-op' para esta distorção. Aqui está um exemplo do site original, usando os coeficientes fornecidos para a câmera que foi usada para tirar a foto.

  magick barrel_distorted.jpg -virtual-pixel black \
          -distort Barrel "0.0 0.0 -0.075 1.1" \
          barrel_distorted_fixed.jpg

[IM Output] [IM Output]

Note como a distorção na imagem foi corrigida, tornando as colunas do edifício retas. Entretanto, como os 4 coeficientes somaram um valor maior que 1.0, a imagem foi encolhida em uma pequena quantidade, produzindo as pequenas áreas pretas no meio das bordas superior e inferior (de acordo com a Configuração de Pixel Virtual fornecida). Aqui está o efeito de adicionar 0.2 a cada um dos coeficientes de entrada; novamente os valores somam mais que 1.0, então a imagem distorcida resultante será menor.

  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.2 0.0 0.0 1.0"   barrel_checks_A.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.2 0.0 1.0"   barrel_checks_B.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 0.2 1.0"   barrel_checks_C.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 0.0 1.2"   barrel_checks_D.png

[IM Output] [IM Output] [IM Output] [IM Output]

Subtrair 0.2 produz o efeito oposto, embora eu tenha compensado o efeito usando um valor 'D ' maior (para encolher a imagem) para que você possa ver melhor os resultados.

  magick checks.png -virtual-pixel gray \
          -distort Barrel "-0.2 0.0 0.0 1.3"   barrel_checks-A.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 -0.2 0.0 1.3"   barrel_checks-B.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 -0.2 1.3"   barrel_checks-C.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 0.0 1.3"    barrel_checks-D.png

[IM Output] [IM Output] [IM Output] [IM Output]

Note como o valor de A produz um efeito maior que B , e B um efeito maior que C , enquanto D fornece um dimensionamento geral do resultado. Isso permite usar cada coeficiente para ajustar a imagem de modo que você possa corrigir uma distorção ao redor da borda externa e outra distorção em direção ao meio, seja pincushion para uma e barrel para a outra. Muito versátil. Os coeficientes acima (A , B , C e D) são projetados para funcionar com um raio 'normalizado' que é a metade da menor largura ou altura da imagem (como a configuração de raio '0' para Distorção Polar. Ou seja, eles são independentes do tamanho da imagem. Assim, você pode usar o mesmo conjunto de valores para qualquer imagem que uma câmera específica gere, independentemente de seu tamanho de qualidade (configuração da câmera), ou se você redimensionou a imagem para menor. É possível ajustar os valores dos coeficientes para usar outros valores de raio 'normalizado' usando os multiplicadores/divisores apropriados em cada coeficiente. Como usar a metade da maior largura/altura, ou usar o raio diagonal. | _Helmut Dersch também observa que você deve considerar usar um espaço de cor LAB para correção de distorção em fotos, pois ele produz melhor interpolação de cor. Isso pode na verdade ser verdade para todas as distorções (incluindo Redimensionar.

Testes mostram que o espaço LAB é tão não linear quanto o sRGB, mas evita a possibilidade de distorções de cor quando valores extremos são cortados. Veja Percepção Humana de Cor, e os exemplos práticos em Redimensionamento com Correção de Espaço de Cor._
---|---

Você também pode declarar um conjunto diferente de coeficientes para os eixos x e y, permitindo gerar algumas distorções incomuns.

_A x Bx Cx Dx Ay By Cy Dy_ [ _X_ , _Y_ ]

O uso de argumentos X e Y separados foi prototipado no script pinbarrel de Fred Weinhaus, embora seus argumentos estejam na ordem inversa, com D primeiro e A por último. Usando um valor C positivo, com um valor D apropriado apenas para o conjunto 'y' de coeficientes, você pode distorcer imagens de modo que elas se projetem verticalmente no meio. |

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Barrel "0.0 0.0 0.0 1.0   0.0 0.0 0.5 0.5" \
          barrel_bulge.png

[IM Output]
De modo semelhante, usando um valor C negativo, você pode 'apertar' uma imagem no meio. |

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Barrel "0.0 0.0 0.0 1.0   0.0 0.0 -0.5 1.9" \
          barrel_pinch.png

[IM Output]
Ou, adicionando o efeito oposto para os coeficientes X, fazer parecer que você está espremendo a imagem entre os dedos, fazendo-a projetar-se para os lados. |

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Barrel "0.0 0.0 0.5 0.5   0.0 0.0 -0.5 1.9" \
          barrel_pinch_2.png

[IM Output]

Distorção BarrelInverse (distorção barrel alternativa)

O método de distorção 'BarrelInverse' é muito semelhante ao método de distorção Barrel anterior, e de fato recebe o mesmo conjunto de argumentos. Entretanto, a fórmula aplicada é ligeiramente diferente, com a parte principal da equação dividindo o raio. Ou seja, a equação foi invertida.

_R src_ = r / ( A*_r 3_ + B*_r 2_ + C*_r_ + D )

| Esta equação NÃO produz o 'inverso' da distorção 'Barrel'. Você NÃO pode usá-la para 'desfazer' a distorção anterior.
---|---
O resultado disso é que você usaria a forma 'negativa' de A , B , C , com um ajuste equivalente em D para obter um resultado semelhante, mas ligeiramente diferente. Algumas fontes, como o artigo de pesquisa Method for Correcting Lens Distortion (PDF), sugerem que um resultado melhor pode ser obtido com uma distorção de correção de lente desta forma. Por exemplo, aqui está o equivalente do último exemplo 'Pinch' usando esta forma de distorção. |

  magick rose: -alpha set -virtual-pixel transparent \
          -distort BarrelInverse "0.0 0.0 -0.5 1.5   0.0 0.0 0.3 0.5" \
          barrel_inv_pinch.png

[IM Output]


Distorções Projetivas

Estas são distorções usadas para projetar ou mapear imagens que existem em uma superfície sobre outra superfície. As linhas projetivas podem ser paralelas ou irradiar de algum local específico. Embora tecnicamente as Distorções Affine e Perspectiva também sejam 'projetivas', no sentido de que 'projetam' imagens de uma superfície plana sobre outra superfície plana (usando projeções paralelas e radiais, respectivamente), elas são tão comuns que são examinadas em maior detalhe em suas próprias áreas de exemplo acima. Aqui estão as 'Distorções Projetivas' mais incomuns que foram implementadas, normalmente com a ajuda do Fórum de Discussão do IM.

Cylinder 2 Plane

A distorção 'Cylinder2Plane' é uma distorção projetiva radial de um ponto no centro de um cilindro para um plano que é tangente a esse cilindro.

[diagram]

Este arranjo é típico de uma câmera pinhole especial conhecida como câmera P.90. onde uma foto de arco de 90 graus é capturada em um filme que forma um cilindro na câmera. Aqui está um exemplo de foto de tal câmera...

[photo]

O problema com isso é que a imagem resultante fica distorcida, de modo que linhas retas se tornam arcos curvos, devido ao arranjo físico do filme. Essencialmente uma superfície curva envolvendo-se em torno de uma fonte de projeção 'pontual' (um pinhole). Note que uma câmera pinhole normal não tem esse problema, pois você está projetando sobre uma superfície plana a partir de uma fonte pontual. A distorção 'Cylinder2Plane' corrige isso projetando a imagem de seu arranjo cilíndrico sobre um plano. Ela recebe os parâmetros...

_fov_angle center_x,y fov_output dest_center_x,y_

Apenas o primeiro parâmetro, o ângulo do campo de visão da câmera, é obrigatório. Para uma câmera P.90, ela usava uma distância focal (radial) de 90mm e um filme padrão de 57mm de largura, o que por sua vez produz um 'campo de visão' de 90 / 57 * 180/pi ou 90.467 graus. Aqui, por exemplo, projeto uma foto P90 sobre um plano para fazer a imagem parecer mais 'normal' e tornar as linhas retas retas novamente.

  magick p90_orig.jpg -virtual-pixel Gray \
          +distort Cylinder2Plane 90.467  p90_plane.png

[IM Output]

Note que tanto a largura quanto a altura da imagem mudaram, pois estamos usando a versão 'plus' da distorção, de modo a mostrar todos os pixels distorcidos na imagem original. Ela fica mais larga por causa da projeção, enquanto a altura da imagem real ao longo da linha central vertical não mudou. A foto e o algoritmo vieram de uma discussão do IM Correcting for a curved film plane. A discussão também derivou para outra discussão sobre Algorithmic vignetting correction for pinhole cameras.
O especial 'fov_output ', se fornecido, dimensionará a imagem de saída resultante de modo que a largura da imagem de saída (normalmente um tamanho de viewport) corresponda exatamente a esse ângulo. Se nenhum viewport for fornecido, é habilitada uma melhor correspondência, para melhor aproximar um dimensionamento 1:1 da imagem, mantendo ainda o alinhamento das bordas da imagem a inteiros. O parâmetro de ponto central da distorção (ponto tangente e de horizonte da entrada). O último parâmetro 'center' controla o posicionamento preciso em ponto flutuante dos resultados na 'camada' da imagem do viewport (ou seja, translações subpixel). Isso, junto com o parâmetro 'center_x,y ', permite extrair partes de uma imagem maior. Por exemplo, extrair uma pequena vista de 90 graus de uma imagem panorâmica maior de 360 graus. FUTURO: extrair imagens de 'visualização' planas menores de um panorama de 360, bem como uma animação que percorre lentamente esses 360 graus.

Plane 2 Cylinder

A distorção 'Plane2Cylinder' é o inverso da projeção acima, e recebe os parâmetros...

_fov_angle center_x,y_

Por exemplo, isto desfaz o exemplo anterior da câmera P.90.

  magick p90_plane.png -virtual-pixel Black \
          +distort Plane2Cylinder 90.467  p90_restored.png

[IM Output]

Os resultados ainda contêm os pixels extras que foram adicionados anteriormente, e adicionam ainda mais. Estes deveriam ser aparados do resultado acima. Aqui uso esta distorção para gerar uma animação de uma 'tira de filme' completa com os furos de perfuração da borda do filme.

  magick -size 12x12 xc: -draw 'circle 6,6 6,2' -negate \
          -duplicate 5 +append +duplicate \
          rose: +swap -background black -append \
          -duplicate 3 +append \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -duplicate 19  -distort SRT '%[fx:72*t/n],0 1 0 0,0' \
          -distort Plane2cylinder 115 \
          -bordercolor Skyblue -border 0x3 -set delay 5 \
          film_strip_anim.gif

[IM Output]

Explicação:

  • Primeiro é desenhada uma imagem de furo, que é duplicada e anexada para formar uma sequência de 6 furos. Depois duplicada novamente.
  • Uma imagem rose interna é então adicionada e ensanduichada entre as duas cópias desses furos de perfuração e anexada (com preenchimento preto) para criar um único quadro da tira de filme final.
  • Isso é duplicado para criar uma tira de filme de 4 quadros, que definirá o comprimento da imagem final.
  • Uma animação de 20 quadros é criada usando distorções de 'translação' SRT. Veja Animações de Distorção.
  • Então cada um desses 20 quadros é distorcido sobre um cilindro em um arco de 115 graus, usando uma configuração de pixel virtual para gerar um ladrilho horizontal infinito da tira de filme
  • O ângulo neste caso é apenas para a largura da imagem de entrada; a largura da imagem final é maior que 180 graus, pois não usei uma versão 'plus' da distorção. Portanto, embora a largura distorcida encolha em largura, a imagem de saída não.
  • Uma borda final é adicionada, e as configurações de animação aplicadas.

Distorções multiponto e de forma livre

Distorção de Shepard (distorção tipo caramelo)

O método de Shepard (adicionado ao IM v6.4.2-4) usa o movimento dos pontos de controle informados para distorcer a imagem em termos de efeitos 'locais'. Você pode pensar nisso como equivalente a um bloco espesso de 'caramelo puxa-puxa' representando a imagem de origem, no qual se cravam pinos que depois são movidos. Mais tecnicamente, ele move pontos em termos de uma Interpolação por Distância Quadrática Inversa. Se apenas um ponto de controle for usado, naturalmente a imagem inteira é movida (transladada), assim como você obteria em uma distorção '[Affine](#affine)' de um único ponto. Não é muito interessante. Então vamos tentar mover dois pontos de controle. Por exemplo, vamos torturar o 'coala' puxando suas orelhas (em '30,11' e '48,29')...

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull.png

[IM Output] [IM Output]

Como você pode ver, as partes da imagem entre os dois pontos de controle foram esticadas por causa do movimento dos pontos de controle. Entretanto, todas as outras partes da imagem ficaram praticamente intactas, incluindo a imagem próxima ao próprio ponto de controle, a parte inferior da imagem, e assim por diante. A área que fica no meio entre os pontos de controle foi puxada e esticada para garantir que os pontos de controle sejam posicionados onde você pediu. O que talvez não seja tão perceptível é que as partes do lado oposto dos pontos de controle também são comprimidas, de modo que, à medida que você se afasta, os pontos de controle têm menos influência sobre o resultado. Ou seja, essa distorção gera uma distorção 'localizada'. Vamos ampliar nossa visão (usando uma viewport de distorção) para conseguirmos ver isso melhor... |

  magick koala.gif -virtual-pixel Black \
          -set option:distort:viewport 115x115-20-20 \
          -distort Shepards '30,11 15,11  48,29 58,29' \
          +repage koala_ear_pull_2.png

[IM Output]
Como você pode ver, o formato da imagem também foi distorcido para acomodar a 'cabeça' esticada do coala. Para evitar esse efeito, é mais comum também 'fixar' os cantos e possivelmente algumas das bordas da imagem, de modo que não se movam. |

  magick koala.gif -virtual-pixel Black \
          -set option:distort:viewport 115x115-20-20 \
          -distort Shepards '30,11 15,11  48,29 58,29
              0,0 0,0  0,74 0,74   74,0 74,0  74,74 74,74' \
          +repage koala_ear_pull_3.png

[IM Output]
Mesmo mover apenas um ponto, enquanto se fixam outros pontos (apenas os cantos, neste caso), pode ser útil. Por exemplo, vamos apenas mover o nariz do coala (em '28,24') para o meio da imagem. |

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '28,24 37,37
              0,0 0,0  0,74 0,74   74,0 74,0  74,74 74,74' \
          +repage koala_move_nose.png

[IM Output]
Este exemplo específico é especial por ser a distorção usada por Fred Weinhaus em seu script de 'metamorfose animada' de ponto único "[shapemorph](http://www.fmwconcepts.com/imagemagick/shapemorph/)". Entretanto, seu script original usava um lento Operador FX DIY, pois a Distorção de Shepard ainda não havia sido adicionada ao IM. Esse script foi na verdade a origem da ideia original da Distorção de Shepard.

Movendo áreas de uma imagem

Você pode até mover seções inteiras da imagem movendo um conjunto de pontos ao redor dessa seção em conjunto. Por exemplo, vamos mover a cabeça do coala de lado usando pontos ao redor da cabeça (linha vermelha), mas também fixando as partes da imagem que não queremos mover (linha verde).

  magick koala.gif -virtual-pixel Black -distort Shepards \
            '19,8, 29,8   19,27 29,27   26,34 36,34
                 33,37 43,37   36,37 46,37   53,37 63,37   58,25 68,25
             13,20 13,20  17,28 17,28  25,36 25,36
                 35,39 35,39   46,40 46,40   50,43 50,43 ' \
          +repage koala_head_move.png

[IM Output] [IM Output]

Observe que, embora a cabeça tenha sido movida, a borda da cabeça acaba muito distorcida. A razão é que a distorção não move áreas, mas pontos. Se esses pontos que marcam a borda estiverem muito afastados, a imagem tende a escorrer, vazar ou dobrar entre esses pontos, como caramelo ou gelatina. (À PARTE: o termo real é esticar uma 'folha de borracha' ou 'balão'). Além disso, se dois pontos de controle estiverem próximos, mas se moverem em direções ou quantidades diferentes, a imagem pode girar em espiral e dobrar localmente ao redor deles. Os pontos de controle ainda acabam nas posições corretas, mas tudo ao redor deles fica severamente empenado para atingir esse objetivo. E é isso que acontece ao longo da borda da cabeça. Então, quão próximos devem estar os pontos que marcam a borda? Basicamente, pelo menos metade da distância até quaisquer outros pontos que se movam de forma diferente. Então, ou adicione mais pontos de borda, ou coloque uma distância extra entre os pontos fixos e os pontos em movimento. Ao fazer isso, você definirá melhor o espaço no qual a imagem pode ser esticada e comprimida. Observe também que a imagem inteira, em geral, também se moveu para a esquerda, junto com a cabeça. Somente os pontos de controle que foram fixados ou movidos para destinos específicos têm garantia de serem posicionados corretamente. Quaisquer partes da imagem mais distantes de qualquer ponto de controle também se moverão com base em uma média aproximada de todos os movimentos dos pontos de controle. É, portanto, melhor ter muito mais pontos 'fixos', espalhados por toda a imagem, ou até mesmo alguns pontos movidos negativamente a certa distância fora da imagem, para compensar o movimento médio geral. Você também pode duplicar ou repetir pontos de controle (listá-los duas vezes) para dar a pontos específicos mais influência ou 'poder' sobre a distorção naquela área. Aqui está outra versão do 'mover a cabeça de lado', porém desta vez dei uma separação extra entre os pontos em movimento (vermelho) e os fixos (verde). Também adicionei muito mais pontos fixos para reduzir o movimento geral médio da imagem distorcida.

  magick koala.gif -virtual-pixel Black -distort Shepards \
            '15,15, 25,15   19,27 29,27   26,34 36,34
                33,37 43,37   36,37 46,37    53,37 63,37
             10,2 10,2   2,10 2,10   4,55 4,55   14,47 14,47
                25,47 25,47 45,51 45,51   55,45 55,45
                5,70 5,70  15,60 15,60   55,60 55,60   70,70 70,70' \
          +repage koala_head_move_2.png

[IM Output] [IM Output]

A última coisa a fazer no exemplo acima é simplesmente definir uma configuração "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" melhor para definir qual cor as áreas pretas indefinidas acima deveriam ter.

Shepard e rotações de imagem

Um aspecto dessa distorção é que ela não gosta de nenhuma forma de rotação! Por exemplo, aqui está uma repetição da Perspective e da BilinearForward, ao lado da Distorção de Shepard.

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort Perspective \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_pers.jpg

  magick mandrill_grid.jpg -alpha set -virtual-pixel black -interpolate Spline \
       -distort BilinearForward \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_blin.jpg
  magick mandrill_grid.jpg -alpha set -virtual-pixel black -interpolate Spline \
       -distort Shepards \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_shep.jpg

[IM Output]
Original | | [IM Output]
Perspective | [IM Output]
Bilinear | [IM Output]
Shepards
---|---|---|---|---

Observe como a Distorção de Shepard produziu uma imagem muito curva quando comparada aos outros dois métodos de distorção. Isso ocorre porque ela tenta preservar a imagem exatamente na área próxima aos pontos de controle informados. E isso inclui a rotação da imagem. Como resultado dessa 'preservação', a grade é curvada de modo a permanecer 'ortogonal' no ponto de controle real. É um pouco como se aqueles 'pinos' nos pontos de controle não fossem realmente pinos redondos, mas 'cruzes', forçando a 'gelatina' ou 'folha de borracha' que sustenta a imagem a também preservar a rotação da imagem. Essa é também a origem de muitos dos efeitos de 'redemoinho' que essa distorção pode produzir. Por exemplo, se pegarmos dois pontos na imagem e os empurrarmos um além do outro. A imagem irá rodopiar, não rotacionar. Por exemplo, vamos tentar empurrar as orelhas do coala uma em direção à outra, em vez de afastá-las.

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '30,11 40,11  48,29 38,29' \
          koala_ear_push.png

[IM Output] [IM Output]

Fator de potência de Shepard

Normalmente, os pesos de distância de um IWD (Distância Ponderada Inversa) de Shepard seguem uma lei do inverso do quadrado (1/r2), porém, a partir do IM v6.8.0-10 você agora pode usar o define avançado 'shepards:power' para controlar o 'nível de potência' dos pesos globais. Se não for definido, ele tem valor 2.0, mas ao defini-lo menor você pode gerar distorções mais localizadas ao redor dos pontos de controle movidos, a partir do deslocamento médio geral da imagem distorcida. Usar um valor maior gerará uma área de efeito maior ao redor dos pontos de controle. Por exemplo, aqui está uma repetição do exemplo de 'puxar as orelhas do coala', com diferentes níveis de potência aplicados aos pesos da distorção.

  magick koala.gif -virtual-pixel Black -define shepards:power=0.5 \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull_pow0.5.png
  magick koala.gif -virtual-pixel Black -define shepards:power=1.0 \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull_pow1.png

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull.png
  magick koala.gif -virtual-pixel Black -define shepards:power=3.0 \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull_pow3.png
  magick koala.gif -virtual-pixel Black -define shepards:power=8.0 \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull_pow8.png

[IM Output]
Original
& ação | | [IM Output]
potência 0.5 | [IM Output]
potência 1.0 | [IM Output]
potência 2.0
(padrão) | [IM Output]
potência 3.0 | [IM Output]
potência 8.0
---|---|---|---|---|---|---

Todos os resultados de imagem acima usam exatamente o mesmo conjunto de movimentos dos pontos de controle. A única diferença é a área de efeito ao redor desses pontos de controle. Uma potência pequena 'localiza' os movimentos apenas na área próxima ao ponto de controle, enquanto potências maiores arrastam mais da imagem ao redor do ponto de controle junto com ele. Em potências muito grandes, esse puxão tende a 'rasgar' a imagem em áreas separadas ao longo das linhas equidistantes entre os pontos de controle. Você poderia até usar potências muito maiores, que simplesmente transladam regiões ao redor do ponto de controle de origem para áreas ao redor do ponto de controle de destino. Essas áreas formarão um padrão de 'regiões de voronoi' e podem conter cópias duplicadas da imagem de origem. Por exemplo, aqui eu mapeio a área ao redor do nariz do coala (nas coordenadas 28,24) em 7 áreas diferentes em um padrão hexagonal, produzindo um efeito parecido com 'olho de inseto' de maneira muito eficiente. |

  magick koala.gif -virtual-pixel Black -define shepards:power=25 \
          -distort Shepards '28,24 35,35 \
                      28,24 20,10   28,24 50,10 \
                      28,24 20,60   28,24 50,60 \
                      28,24 10,35   28,24 60,35'  koala_hexagonal.png

[IM Output]
Lembre-se de que a Distorção de Shepard é na verdade equivalente a um mapa de deslocamento (mapeando pixels de destino para a imagem de origem) gerado com a mesma técnica do Operador Shepards, Sparse Color, que também é afetado por esse mesmo define de fator de potência.

Distorção de Shepard, em resumo

A Distorção de Shepard é um método muito versátil e de forma livre, limitando suas distorções às áreas marcadas pelos movimentos, ou não movimentos, dos pontos informados. Suas distorções são localizadas e restritas de acordo com as distâncias entre pontos de controle vizinhos, embora todos os pontos ainda tenham um efeito global médio. Apenas lembre-se de que essa distorção é orientada por pontos, não por linhas ou áreas, então as partes entre os pontos podem inchar ou rodopiar inesperadamente quando pontos de controle, que se movem de forma diferente, ficam posicionados muito próximos. Ela irá rodopiar, esticar e comprimir a imagem entre os pontos de controle, mas se esforça para não rotacionar nem escalar a imagem perto dos pontos de controle. E, finalmente, pode produzir uma translação média geral da imagem em locais distantes de qualquer ponto de controle. Entretanto, se blocos de pontos de controle puderem ser movidos, preservando suas posições relativas gerais, ela fornece uma maneira de implementar uma técnica de 'Metamorfose de Imagem' geral e muito simples, orientada por pontos. O script 'shapemorph2' de Fred Weinhaus usa a Distorção de Shepard para fornecer um bom programa de propósito geral de 'Metamorfose Animada de Imagem'. Internamente, essa distorção é equivalente a usar o gerador de gradienteShepards Sparse Color para criar dois Mapas de Deslocamento Relativo para distorcer a imagem. É isso que o script "[shapemorph](http://www.fmwconcepts.com/imagemagick/shapemorph/)" original de Fred Weinhaus faz, e foi a origem da técnica de distorção.
Devido à complexidade dos cálculos necessários ao usar aDistorção de Shepard, o IM não fornece nenhuma forma de janela de exibição de destino de 'melhor ajuste' usando a forma com mais "[+distort](#distort_bestfit)" do operador. Você ainda pode, no entanto, usar a opção viewport de distorção para definir uma imagem de saída maior.
--- ---
Pelas mesmas razões, aReamostragem por Área fica desativada. Assim, áreas de compressão extrema (mais de um fator de 2) provavelmente mostrarão alguns efeitos de aliasing. Por exemplo, veja as bordas do padrão hexagonal no último exemplo. Entretanto, a Superamostragem pode ser usada para melhorar a qualidade final da imagem dos resultados e reduzir esses efeitos de aliasing.
--- ---