⚠️ Ceci est un site de traduction non officiel, sans lien avec ImageMagick Studio LLC. Pour des informations officielles, consultez la page originale (https://usage.imagemagick.org/distorts/index.html).

Exemples ImageMagick -- Déformation des images

Après avoir examiné le jeu simple d'opérateurs d'enroulement et de déformation d'images intégrés que IM fournit depuis ses débuts, nous allons ici approfondir et étudier les mécanismes internes ainsi que les déformations mathématiques plus complexes des images. À partir de cette compréhension plus poussée, nous nous tournerons vers un opérateur de déformation d'images plus généralisé. Cela couvre les déformations, des rotations, mises à l'échelle et cisaillements complexes, jusqu'aux déformations en perspective ou 3D, à l'enroulement vers et depuis des arcs de cercle, aux distorsions d'objectif photographique, et enfin à des déformations plus générales, proches du morphing.


Techniques générales de déformation

Maintenant que les opérateurs de déformation simples fournis par IM ont été présentés, prenons du recul pour examiner les détails concrets, voir comment les déformations d'images fonctionnent réellement et comment améliorer la manière de les utiliser. Plus loin, nous aborderons des façons bien plus complexes de déformer les images, y compris des méthodes qui ne sont pas directement intégrées à ImageMagick. Il n'existe que quelques manières fondamentales pour un processeur d'images de déformer une image. Les opérateurs de Déformation simple, par exemple, s'obtiennent par échange de pixels. Autrement dit, des pixels individuels, voire des lignes et colonnes entières de pixels, sont simplement permutés pour réaliser le Retournement, le Défilement, la Transposition et même les Rotations rectangulaires d'images. Aucun changement de couleur n'est effectué, et le nombre de pixels reste identique. La méthode de déformation suivante consiste à décaler ou cisailler les colonnes et les lignes de pixels, horizontalement ou verticalement, comme le fait IM avec le Cisaillement d'image et la Déformation en vague ci-dessus. Les cisaillements offrent à leur tour une méthode pour Pivoter des images selon n'importe quel angle donné, d'une manière qui devrait être assez rapide. Cependant, les méthodes de décalage de pixels se limitent à ces déformations de base. Elles ne peuvent pas, par exemple, mettre une image à l'échelle vers une taille différente. Vous avez aussi très peu de contrôle sur le traitement des zones de l'image résultante qui n'étaient pas couvertes par l'image source d'origine. Dans les fonctions mentionnées ci-dessus, IM se contente de remplir les zones manquantes avec la couleur d'arrière-plan courante. Pour pouvoir déformer les images d'une façon bien plus générale, il faut recourir à une technique de déformation plus générale appelée cartographie inverse des pixels. Cette méthode est par exemple employée par les Déformations circulaires plus complexes, telles que l'Implosion et le Tourbillon d'images.

Cartographie directe des pixels

La première chose à laquelle on pense en essayant de déformer une image est de prendre chaque pixel de l'image source et de le déplacer directement vers son nouvel emplacement dans l'image de destination. En fait, c'est plus ou moins ce qui se produit pour les Déformations simples, le Recadrage d'image et même pour la déformation d'images vectorielles. Chaque pixel (ou coordonnée) est simplement déplacé vers sa nouvelle position dans l'image finale. Malheureusement, cela pose problème dès que l'on tente de le faire pour autre chose qu'une déformation simple. Par exemple, je prends ici une liste de pixels énumérés d'une petite image et je change simplement l'emplacement de chaque pixel, afin de le faire pivoter vers son nouvel emplacement. |

  # 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]
La déformation est une simple rotation de seulement 17 degrés, mais le résultat n'est vraiment pas bon du tout. Tout d'abord, chaque nouvel emplacement de pixel est une valeur en virgule flottante, or les pixels ne peuvent exister que sur une grille d'entiers ; le code ci-dessus jette donc simplement la partie fractionnaire non entière des résultats. Le deuxième problème est que le résultat est criblé de trous là où aucun pixel n'a atterri. Ce qui amène le troisième problème. Vous ne le voyez peut-être pas, mais pour chaque trou de l'image résultante, vous trouveriez aussi un autre emplacement où deux pixels ont été placés. Autrement dit, vous avez plusieurs pixels au même endroit. Quelle valeur de pixel faut-il utiliser ? Dans l'exemple ci-dessus, IM a simplement utilisé le dernier pixel défini pour un emplacement. En d'autres termes, l'image résultante est incomplète : chaque pixel de la destination n'est pas exactement là où il devrait être, et peut correspondre à plusieurs pixels, ou à aucun. Ce sont de sérieux problèmes, qu'il n'est pas facile de résoudre lorsqu'on cartographie directement les pixels de l'image source vers l'image de destination. Cela ne veut pas dire que ça ne peut pas fonctionner : de nombreux articles de recherche évoquent l'usage d'une technique appelée « splatting ». En gros, on prend chaque pixel d'entrée, on transforme son emplacement, puis on le dessine avec un étalement et un mélange appropriés des couleurs de pixels au nouvel emplacement. Cette technique est particulièrement utile pour la numérisation 3D d'objets du monde réel. On dispose alors d'un « nuage » de points de surface de couleur connue. Tout point visible pour l'utilisateur est simplement « splatté » sur l'écran de façon à produire une image finale. Avec suffisamment de points, l'image paraîtra complète. Combinée à des commandes 3D interactives, cette approche fonctionne très bien et est très rapide. Le splatting de points en trois dimensions dépasse toutefois le cadre de IM, qui traite des images matricielles 2D.

Cartographie inverse des pixels

Plutôt que d'essayer de cartographier les pixels vers l'image finale, vous pouvez cartographier la coordonnée de chaque pixel de l'image de destination vers l'emplacement correspondant dans l'image source, puis rechercher dans cette image source la couleur que ce pixel devrait contenir. C'est ce qu'on appelle une cartographie inverse des pixels, et c'est ce que fait à peu près tout programme de déformation d'images. Comme chaque pixel de l'image de destination est traité, on peut être certain que chaque pixel de la destination reçoit une et une seule couleur. Ainsi, du moment que l'on parvient à déterminer l'emplacement « source » de chaque pixel de destination, on peut déformer une image source en image de destination à l'aide de n'importe quelle formule mathématique imaginable.

[Diagram]

En résumé, une cartographie de déformation (cartographie inverse) procède comme suit.

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

Notez que j'ai utilisé les noms de variables « I,J » et « X,Y » ci-dessus, car ces variables correspondent aux noms de variables que l'on utilise généralement avec l'Opérateur FX à faire soi-même. Par exemple, je simule ici la même rotation de 17 degrés tentée précédemment, mais cette fois en utilisant l'opérateur « [-fx](https://imagemagick.org/command-line-options/#fx) » pour rechercher le pixel le plus proche de cet emplacement dans l'image source. |

  # 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]
Vous trouverez plus de détails sur l'exemple « à faire soi-même » ci-dessus dans la sous-section Cartographie de déformation affine à faire soi-même. Comme vous pouvez le constater, notre image ne comporte plus de « trous » puisqu'une couleur est recherchée pour chacun des pixels de la destination. Le rendu n'est toujours pas très beau, mais c'est une question de réglage de la couleur exacte à placer dans chaque pixel. Autrement dit, la cartographie inverse des pixels ne génère ni trous ni pixels superposés. Chaque pixel possède une couleur correctement définie, produisant une image complète.
La distinction entre cartographie directe et inverse est importante, car la plupart des transformations mathématiques sont définies comme des cartographies directes, faisant correspondre une unique position source (X,Y) à une position de destination (I,J). Et de fait, une « cartographie directe » fonctionne bien pour les graphiques vectoriels et le tracé de lignes, où il suffit de cartographier les extrémités de la ligne et de la dessiner. C'est particulièrement vrai pour toute transformation linéaire, comme les rotations, où les lignes restent droites. C'est d'ailleurs ce qui est fait dans tous les langages vectoriels tels que postscript et SVG. Mais pour une image matricielle générale, il faut recourir à une « cartographie inverse » pour déformer l'image, afin d'être certain de « remplir » tous les pixels de l'image de destination. Par exemple, si vous examinez les formules mathématiques employées pour cartographier les coordonnées dans les deux cas ci-dessus, vous constaterez qu'elles se ressemblent presque exactement. La cartographie inverse d'une « rotation » est une autre « rotation », simplement dans le sens opposé. En regardant de près, vous verrez que la constante « sin » est prise avec un signe opposé par rapport à la version cartographiée directement, et cela suffit à inverser le sens de rotation. Ce détail est important et crucial. Le problème est que toutes les transformations en cartographie directe ne fonctionnent pas bien en tant que transformation inversée. Certaines cartographies directes n'ont en fait pas de cartographie inverse directe simple. Cela ne veut pas dire que c'est impossible, mais simplement que ce n'est pas simple. À l'inverse, certaines transformations d'images fonctionnent très bien en cartographie inverse, mais n'ont pas de cartographie directe simple. Recourir à la méthode de cartographie inverse présente donc à la fois des avantages et des inconvénients sur le plan mathématique.
À titre d'information, voici l'équivalent plus rapide de l'exemple ci-dessus, utilisant une méthode de Déformation générale, SRT qui effectue exactement la même rotation de l'image que ci-dessus et produit exactement le même résultat, en plus rapide. Là encore, la recherche de couleur est limitée à la seule couleur du pixel le plus proche de la position cartographiée grâce à l'interpolation « point ». Cela signifie qu'aucune nouvelle couleur n'est ajoutée à l'image (hormis lorsqu'on « manque » l'image source), mais que vous obtenez aussi de sévères effets de crénelage. |

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

[IM Output]
| Pour une autre présentation des transformations de déformation, voirLeptonica, Affine Implementation, et en particulier son exposé sur la méthode « point-wise ». L'autre méthode, « sequential », correspond pour l'essentiel à la façon dont IM implémentait autrefois ses opérateurs de déformation Rotation et Cisaillement.
---|---
Qu'y a-t-il dans un nom ? Au cours de mon étude, j'ai constaté qu'il n'existe pas de nomenclature réellement claire pour cette méthode de traitement d'images. Le processus algorithmique proprement dit est connu sous le nom de « cartographie inverse des pixels », tandis que l'usage d'équations mathématiques est appelé « transformation géométrique ». Si la déformation est pilotée par le déplacement de différents points de contrôle, on parle souvent de « déformation d'image » (image warping) ou de « rubber sheeting ». Le processus consistant à définir des points spécifiques, généralement pour trouver des points équivalents entre deux images ou plus, est appelé « recalage d'image » (image registration). Les images peuvent aussi être subdivisées en unités plus petites et plus simples, déformées individuellement au moyen d'une technique appelée « gridding » (quadrilatères) et « maillage triangulaire » (triangles). En utilisant de petites déformations incrémentales avec un mélange des couleurs de deux images, vous pouvez générer des « morphs d'images » animés, comme on en voit dans les films et les clips musicaux. Si l'on utilise une image de cartographie préparée à l'avance plutôt qu'une recherche mathématique effectuée à la volée, on obtient une « cartographie de déformation absolue » ; si la recherche est un déplacement relatif (le gris à 50 % correspondant à aucun déplacement, c'est-à-dire aucun changement de la coordonnée de recherche), on obtient une « cartographie de déplacement ». Si la cartographie ne fait que modifier légèrement la couleur (ombrage) plutôt que d'effectuer des recherches de déformation, on obtient la « cartographie de surface en relief » (bump mapping), apparentée mais différente. Dans la modélisation 3D et les jeux vidéo 3D, les mêmes techniques servent aussi à donner un type de motif coloré aux surfaces planes et courbes, selon une méthode appelée « cartographie de texture ». Cela peut impliquer de subdiviser les images en grilles et maillages approchant le pixel unique. On peut alors visualiser un objet défini au moyen de millions de points uniques grâce à une technique appelée « point splatting », bien que celle-ci s'applique généralement à l'aide d'une déformation en cartographie directe. Tout ce qui précède est très étroitement lié et repose, pour l'essentiel, sur la recherche de la couleur d'un pixel en cartographiant une coordonnée de destination finale vers l'image source (ou l'objet). En d'autres termes, une cartographie de la destination vers la source. Quel terme faut-il employer... À vous de choisir.

Recherche de la couleur des pixels

La technique de cartographie inverse des pixels ci-dessus pose encore quelques problèmes. Le premier est que, lorsqu'on cartographie un pixel depuis une position entière fixe de la destination, on peut aboutir à une position non entière dans l'image source. C'est-à-dire un emplacement qui tombe quelque part entre les pixels individuels de l'image source. Pour déterminer la couleur à renvoyer, on utilise un processus appelé Interpolation qui détermine la couleur finale de cette position réelle en mélangeant les couleurs des pixels environnants. Le réglage d'Interpolation gère aussi le cas où une partie d'une image déformée est « étirée », de sorte qu'un unique pixel source se retrouve étalé sur une large zone de l'image de destination. En revanche, le cas inverse n'est pas très bien géré par une simple méthode d'interpolation. Il requiert d'autres techniques que nous verrons ci-dessous. Par exemple, nous faisons ici de nouveau pivoter notre koala, mais cette fois avec un réglage « [-interpolate](https://imagemagick.org/command-line-options/#interpolate) [Mesh](misc.html#mesh) » pour mélanger les quatre pixels voisins et produire une couleur meilleure et plus correcte à partir de la recherche. |

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

[IM Output]
Comme vous pouvez le constater, en fusionnant simplement les couleurs voisines les plus proches entourant le point de recherche non entier, on peut grandement améliorer l'apparence de l'image déformée. Mais d'autres problèmes se posent... Par exemple, que faire lorsque la position cartographiée « manque » complètement l'image source ? Dans ce cas, la couleur à renvoyer est déterminée par le réglage Pixel virtuel. Ce réglage choisira une couleur : celle du bord le plus proche de l'image source, ou en faisant comme si l'image source était infiniment répétée en mosaïque (ou en mosaïque miroir) sur le plan, ou encore une couleur spécifique telle que « blanc », « noir » ou « transparent », ou la couleur d'arrière-plan définie par l'utilisateur. Il est aussi possible qu'aucune coordonnée mathématiquement valide n'existe pour une position de destination donnée en cours de cartographie. Par exemple, le pixel regarde vers le « ciel » d'un « plan » en perspective (voir Contempler des horizons lointains), et ne voit donc même pas le « plan » dans lequel se trouve l'image source. Dans ce cas, un Pixel virtuel est inutile, car il ne « touche » pas le plan de l'image source dans un espace à N dimensions, et le pixel de destination est de ce fait totalement invalide ! IM utilise alors le réglage « [-alpha set](https://imagemagick.org/command-line-options/#alpha) » courant pour la couleur du pixel. S'il s'agit d'un « quasi-manqué », IM appliquera un anticrénelage entre cette couleur invalide et les couleurs voisines du plan de l'image, s'il sait comment procéder. Il le fait pour les déformations en perspective.

Suréchantillonnage

L'interpolation fonctionne bien pour les déformations d'images simples. Mais si une partie de l'image source se retrouve comprimée dans une zone bien plus petite, chaque pixel de destination pourrait en réalité nécessiter la fusion d'une zone bien plus vaste de l'image source. Rappelez-vous que les pixels ne sont pas réellement des points, mais représentent une zone rectangulaire d'une image réelle. Cela signifie que, dans certains cas, nous devrions vraiment essayer de comprimer une large zone de l'image source dans un unique pixel de destination. Lorsque cela se produit, une simple recherche de pixel échoue, car elle ne recherche la couleur qu'en un unique « point » de l'image source (à l'aide du voisinage de pixels environnant), et ne fusionne ni ne combine toutes les couleurs de l'image d'entrée qui devraient être comprimées dans ce pixel unique. Il en résulte qu'un pixel de destination peut se retrouver avec une couleur essentiellement aléatoire de l'image source, plutôt qu'avec une moyenne de toutes les couleurs concernées. Ce n'est pas mauvais en soi, mais lorsque tous les pixels d'une zone font de même, on obtient des images avec des pixels apparemment aléatoires et isolés, des effets de moiré et des effets d'« escalier » crénelés. Les lignes fines finissent aussi par ressembler davantage à des pointillés et des tirets (voir les exemples de l'Opérateur Sample), ou peuvent disparaître entièrement. Tous ces effets sont désignés collectivement sous le nom d'Artefacts de crénelage. Une solution consiste à effectuer davantage de recherches de couleur dans l'image source, pour chacun des pixels de la destination, afin de tenter de déterminer une couleur plus correcte pour chaque pixel de l'image de destination. La solution la plus simple est généralement appelée suréchantillonnage ou sur-échantillonnage. Voir l'article Wikipedia sur le suréchantillonnage. En prélevant davantage d'échantillons de l'image source, sur la zone qui se cartographiera vers chaque pixel de destination, la couleur finale de ce pixel deviendra une représentation plus fidèle de l'image déformée en ce point. Plus vous prélevez d'échantillons de couleur, plus la couleur finale sera précise, et plus le rendu sera lisse et réaliste, même si la déformation devient plus lente. Rappelez-vous que cette technique n'améliore réellement l'apparence générale de la destination que dans les zones où l'image source est comprimée de plus de 50 %. Dans les zones où la déformation agrandit l'image source, ou conserve à peu près la même échelle, une unique recherche interpolée de l'image source produira généralement un bon résultat avec une seule recherche. Dans les exemples d'enroulement par Implosion d'images (et bien d'autres exemples à travers les exemples IM), j'ai brièvement abordé la méthode la plus simple de « suréchantillonnage ». En gros, on agrandit la taille de l'image de sortie (ou, dans ce cas, simplement l'image d'entrée), puis on effectue la déformation. Une fois la déformation terminée, on redimensionne l'image à sa taille normale, ce qui fusionne tous les « échantillons » supplémentaires générés. Par exemple...

  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]
Implosion normale d'une image de boîte | [IM Output]
Implosion suréchantillonnée
---|---

Bien sûr, plutôt que d'agrandir l'image d'entrée, vous pourriez partir d'une image source de meilleure qualité (plus grande), ou en générer une lors d'une étape de traitement antérieure. Si vous en disposez. C'est particulièrement utile lors de la rotation de texte, qui présente souvent de très fins détails devant être préservés uniformément pour garantir un beau rendu de haute qualité dans l'image finale. Pour des exemples, voir la Transformation Polaroid. À partir de IM v6.4.2-6, l'Opérateur de déformation général peut directement générer une image de sortie agrandie, que vous pouvez ensuite réduire (mise à l'échelle ou redimensionnement) pour fusionner et suréchantillonner les pixels résultants. Voir Réglage de l'échelle de déformation, ainsi que l'exemple suivant.
Ce n'est là qu'une seule méthode de suréchantillonnage (dite méthode « grille »), mais il existe de nombreuses autres variantes. Ces méthodes pourront à terme être implémentées plus directement dans ImageMagick, mais pour l'instant, un simple agrandissement puis une mise à l'échelle des images fonctionnent tout à fait bien, sans aucun codage supplémentaire. Un dernier avertissement. Le suréchantillonnage est limité par le nombre d'échantillons utilisés pour chaque pixel de l'image finale, et donc par l'ampleur de la mise à l'échelle utilisée lors du redimensionnement final. Cela détermine la « qualité » finale de l'image déformée. Mais en utilisant des facteurs de mise à l'échelle plus grands, l'image déformée sera bien sûr beaucoup, beaucoup plus lente à générer. Obtenir une qualité encore plus élevée a toutefois ses limites. À l'extrême, le suréchantillonnage ne pourra gérer aucune déformation d'image faisant intervenir des infinis (comme au centre d'une image implosée). Dans de tels cas, une technique totalement différente est nécessaire, telle que celle fournie par le Rééchantillonnage par zone (voir plus bas). En résumé, le suréchantillonnage peut améliorer l'apparence d'images ne présentant que de faibles déformations, comme les rotations, les cisaillements, les transformations affines et les perspectives simples. Mais il a des limites quant aux types de déformations qu'il peut améliorer. Suréchantillonnage adaptatif La technique de suréchantillonnage peut être poussée plus loin. Plutôt que d'utiliser simplement un nombre fixe de recherches de couleur pour chaque pixel, on vérifie soit la distance entre les recherches dans l'image source, soit la proximité des couleurs renvoyées par un échantillonnage de bas niveau, afin de déterminer s'il faut prélever davantage d'échantillons pour ce pixel précis. Autrement dit, la quantité de suréchantillonnage peut s'adapter aux besoins de la déformation, sans rien connaître des spécificités de la déformation elle-même. C'est ce qu'on appelle le suréchantillonnage adaptatif. Cette technique est en réalité très courante dans les moteurs de lancer de rayons (ray tracers), où il est quasiment impossible de déterminer la complexité de l'image résultante en un point donné. Dans ce cas, on se limite souvent à l'usage des « différences de couleur » autour de l'emplacement précis pour déterminer quand davantage d'échantillons sont nécessaires. Si un pixel diffère beaucoup de ses voisins, on utilise davantage d'échantillons dans cette zone pour affiner ce qui est probablement le bord d'un objet tridimensionnel. IM ne prend pas en charge le suréchantillonnage adaptatif pour le moment. Il est toutefois tout à fait possible d'ajouter d'autres méthodes d'échantillonnage à l'Opérateur de déformation général (voir plus bas). Cela nécessitera une certaine réorganisation fonctionnelle du code, si bien que ce ne sera peut-être pas ajouté de sitôt. Résumé du suréchantillonnage La difficulté du suréchantillonnage réside dans la détermination du nombre de « points d'échantillonnage » nécessaires et de la façon dont ces échantillons doivent être disposés dans les limites du sous-pixel. Se pose aussi la question du type de « pondération » à appliquer. Voir l'article Wikipedia sur le suréchantillonnage.

Rééchantillonnage par zone, pour de meilleures déformations

L'une des meilleures alternatives aux méthodes de suréchantillonnage est le rééchantillonnage par zone. Plutôt que de déformer une image plus grande et de moyenner les résultats par redimensionnement — ce qui revient simplement à prélever et moyenner davantage d'échantillons de l'image —, nous déterminons exactement combien de pixels de l'image source doivent être fusionnés (en fonction de l'« échelle » de la déformation en ce point) pour générer chaque pixel de sortie précis. C'est-à-dire qu'on estime une « zone » approximative de l'image source que représente chaque pixel de sortie, et l'on fusionne (filtre) tous les pixels de cette zone selon un filtre de rééchantillonnage. C'est en fait exactement ce que fait l'Opérateur de redimensionnement d'ImageMagick (en réalité un type de déformation d'image très particulier) pour produire d'aussi bons résultats. Cependant, pour le redimensionnement, il suffit de calculer une seule fois pour toute l'image l'échelle de la zone à échantillonner pour chaque pixel. La zone qu'il doit « échantillonner » est un rectangle (fenêtre) de taille fixe dans l'image source, ce qui rend le processus de rééchantillonnage facile et fournit un raccourci dans le processus de déformation. Lors du rééchantillonnage par zone d'une image déformée, la zone de pixels (fenêtre) à échantillonner change non seulement de position, mais aussi de taille. Ainsi, un pixel de la destination peut n'avoir besoin de fusionner que quelques couleurs de l'image source, voire d'une seule recherche de couleur interpolée (comme lors des agrandissements). Tandis qu'un autre pixel ailleurs dans l'image de destination peut devoir échantillonner un très très grand nombre de pixels pour générer la couleur finale correcte. À proximité des infinis, il peut même devoir inclure tous les pixels de l'image source dans le processus d'échantillonnage. De plus, la zone qu'un pixel de destination représente dans l'image source peut ne pas être un simple carré, cercle ou même ellipse, mais peut en réalité être une forme fortement déformée, selon la déformation employée. Calculer et gérer de telles formes complexes peut prendre énormément de temps, voire être quasi impossible. [Diagram] L'usage d'une zone elliptique de l'image source pour calculer les couleurs de chaque pixel de destination est une méthode connue sous le nom de rééchantillonnage par moyenne pondérée elliptique (EWA, Elliptical Weighted Average), présentée dans l'article de recherche PDF « Fundamentals of Texture Mapping and Image Warping » de Paul Heckbert (qui a aussi écrit le programme « zoom » dont dérivent pratiquement tous les algorithmes de redimensionnement d'images). Elle a ensuite servi à définir le nouvel Opérateur de déformation généralisé (voir plus bas). L'ellipse est la forme parfaite pour les Déformations affines comme pour les Déformations en perspective. Elle est particulièrement adaptée aux réductions d'échelle extrêmes (voir l'exemple plus bas). Et bien que non parfaite pour d'autres déformations, elle convient généralement raisonnablement à beaucoup d'autres, telles que les Déformations en arc et polaires (mais pas leurs inverses), ainsi que les déformations radiales comme la Déformation en barillet. Elle convient en revanche mal aux cartographies de déformation non linéaires telles que De-Polar et la Déformation de Shepard ; c'est pourquoi elle n'est pas utilisée pour ces déformations. Le suréchantillonnage n'a pas ce problème de forme, car chaque « échantillon » est cartographié à rebours sur la destination. Il devient donc la meilleure méthode d'échantillonnage dans de tels cas. Mais, comme mentionné, il peut ne pas échantillonner tous les pixels nécessaires, voire en échantillonner trop.

Échantillonnage par zone contre suréchantillonnage

Voici les trois méthodes d'échantillonnage que IM fournit actuellement, appliquées à une image en perspective extrême, infiniment répétée en mosaïque. Voir Contempler des horizons lointains plus bas pour les détails de cette déformation.

  # 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]
Image de damier | | [IM Output]
Recherche
interpolée | [IM Output]
Suréchantillonnage
x10 | [IM Output]
Rééchantillonnage par zone
pondérée elliptique (EWA)
---|---|---|---|---

Toutes les images correspondent exactement à la même déformation, seule la technique de « rééchantillonnage » diffère. La dernière image ci-dessus a utilisé les réglages EWA par défaut de l'Opérateur de déformation généralisé, et comme vous pouvez le voir, elle a produit un résultat de très haute qualité. Elle a toutefois mis 4,6 secondes à être générée, ce qui n'est pas si mal, quoiqu'un peu lent (en raison des extrêmes inhabituels en jeu). La première image a désactivé le rééchantillonnage EWA par défaut au moyen d'un réglage « [-filter](https://imagemagick.org/command-line-options/#filter) point ». Cela la force à utiliser une recherche interpolée directe pour chaque pixel. Cette image a donc été générée extrêmement vite en comparaison (0,51 seconde), mais comme vous pouvez le constater, elle produit un résultat horrible à mesure que la « minification » (sous-échantillonnage) augmente avec la « distance ». L'image du milieu est identique à la première, mais avec l'image de sortie déformée agrandie d'un facteur 10, avant d'être remise à l'échelle (rééchantillonnage par grille) pour correspondre aux autres images. Autrement dit, plus de 100 pixels ont été recherchés et moyennés pour chaque pixel de destination, afin de suréchantillonner le résultat. Elle est assez rapide à générer (1,2 seconde) et, bien qu'elle améliore la qualité de l'image dans l'ensemble, cette amélioration est limitée. Le ×10 utilisé dans l'exemple ci-dessus est très fort, dépassant de loin la mise à l'échelle plus typique de 3 ou 4 fois employée pour la plupart des usages du suréchantillonnage. La plus grande différence entre les résultats est que le suréchantillonnage n'apporte qu'une amélioration générale et uniforme de la qualité sur toute l'image. À mesure que la déformation s'aggrave, il commence à s'effondrer. Le résultat est constitué des artefacts de rééchantillonnage bien visibles dans le plan intermédiaire, et plus précisément d'une ligne de forts effets de moiré juste avant l'horizon. L'effet de moiré est causé lorsque les 10 échantillons prélevés par pixel coïncident presque avec le motif en damier de l'image, produisant des effets de couleur déformés. En revanche, le rééchantillonnage par zone se concentre davantage sur les pixels problématiques proches de l'horizon (où il passe presque tout son temps) que sur les pixels du premier plan, où il surpasse effectivement le suréchantillonnage. En gros, l'exemple ci-dessus est une déformation très extrême, et le temps pris par la recherche EWA est à la mesure de cela. Plus couramment, elle génère de bien meilleurs résultats qu'une simple recherche interpolée, car elle examine efficacement chaque pixel concerné sans utiliser trop d'échantillons dans les zones qui n'en ont pas besoin, contrairement au suréchantillonnage. En résumé... L'usage d'une simple ellipse (rééchantillonnage EWA) ou d'un rectangle (redimensionnement) pour faire du « rééchantillonnage par zone » produit bien de bons résultats, car tous les pixels source impliqués dans des déformations à l'échelle, affines ou en perspective seront fusionnés pour produire la couleur finale d'un pixel de destination individuel. Dans les cas de déformations très non linéaires, comme les Déformations DePolar, ou de déformations indéterminées, comme la Déformation de Shepard, voire le lancer de rayons, trouver la « zone » correcte pour rééchantillonner tous les pixels source nécessaires devient prohibitif, et le suréchantillonnage est la meilleure méthode pour améliorer les résultats. Mais pour de simples mises en mosaïque, agrandissements et rotations non mises à l'échelle, une très rapide recherche interpolée « point » unique est probablement tout ce qui est requis, et peut même être recommandée pour garantir des déformations parfaitement neutres (sans changement) (voir plus bas). Rappelez-vous toutefois que toutes les techniques de rééchantillonnage ne sont que des méthodes pour déterminer la couleur de chaque pixel individuel. Elles ne font pas réellement partie de la façon dont une image est déformée, hormis en ce qui concerne la cartographie des emplacements entre destination et source (ou inversement, si possible).


Opérateur de déformation généralisé

Avec la production de ces exemples, les discussions qui s'ensuivirent dans les forums IM et de multiples demandes d'utilisateurs pour des moyens plus faciles et plus rapides de réaliser des déformations en perspective et autres, un nouvel opérateur a été ajouté à IM v6.3.5-1 afin de nous permettre d'ajouter plus facilement des déformations d'images, de types très variés. Cet Opérateur de déformation généralisé s'appelle « [-distort](https://imagemagick.org/command-line-options/#distort) », et vous pouvez voir quelles méthodes de déformation sont disponibles sur votre version de IM à l'aide de « [-list](https://imagemagick.org/command-line-options/#list) Distort ».

  magick -list distort

L'opérateur « [-distort](https://imagemagick.org/command-line-options/#distort) » prend deux arguments : l'une des méthodes de déformation données ci-dessus, et un second argument sous forme de chaîne constituée d'une liste de valeurs en virgule flottante séparées par des virgules ou des espaces, qui sert à contrôler la méthode de déformation précise.

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

Le nombre de valeurs en virgule flottante à fournir dépend toutefois fortement de la méthode de déformation employée, et leur signification dépend non seulement de la méthode choisie, mais peut aussi dépendre du nombre exact de points de contrôle ou d'attributs nécessaires pour une méthode particulière. C'est particulièrement le cas pour la déformation « [Scale-Rotate-Translate](#srt) » (ou « [SRT](#srt) » en abrégé), qui combine en réalité trois déformations « [Affine](#affine) » distinctes en une seule. De nombreuses méthodes de déformation prennent une liste de points de contrôle (en Coordonnées d'image), et ceux-ci sont généralement donnés sous forme de paires de coordonnées qui contrôlent la façon dont la déformation doit modifier l'image. Ces paires de coordonnées sont détaillées plus complètement plus loin, dans Déformations à l'aide de points de contrôle.

Options, contrôles et réglages de déformation

Indicateur d'ajustement optimal +Distort

Par défaut, « [-distort](https://imagemagick.org/command-line-options/#distort) » déforme généralement la ou les images source vers une image de la même taille que l'image d'origine. Il y a des exceptions, comme la déformation « [Arc](#arc) » (une variante de cartographie polaire) où la taille de l'image source d'entrée n'a réellement pas grand sens sous la forme déformée de l'image (voir Déformation en arc plus bas pour les détails). L'autre forme de l'opérateur, « [+distort](https://imagemagick.org/command-line-options/#distort) » (ajoutée à IM v6.3.5-7), tentera de redimensionner l'image déformée de sorte qu'elle contienne l'intégralité de l'image d'entrée (si possible), un peu comme le font les anciens opérateurs de Rotation et cisaillement. Cependant, ce « mode » de fonctionnement particulier va aussi plus loin et définit également le décalage de canevas virtuel (page) de l'image résultante. Ainsi, vous pourrez ensuite fusionner par calques cette image sur une autre, à la position correcte selon vos points de contrôle, en utilisant la composition alpha appropriée (voir Cubes 3D, par superposition affine pour un exemple de base). De plus (selon la méthode de déformation), un « [+distort](https://imagemagick.org/command-line-options/#distort) » tentera de tenir compte de tout décalage de canevas virtuel existant qui pourrait être présent dans l'image source, et de l'utiliser dans le cadre du processus de déformation. Voir les notes concernant les méthodes de déformation individuelles. Vous pourriez donc avoir besoin de faire un usage judicieux de l'opérateur de réglage d'attribut « [+repage](https://imagemagick.org/command-line-options/#repage) » pour effacer ou ajuster ce décalage avant d'utiliser la forme « ajustement optimal » « [+distort](https://imagemagick.org/command-line-options/#distort) » de l'opérateur de déformation général. Vous pourriez aussi devoir l'employer après, si le canevas virtuel et le décalage ne sont pas requis. Voir aussi Supprimer la géométrie de canevas/page. Le « [-distort](https://imagemagick.org/command-line-options/#distort) » normal ignorera simplement tout décalage existant présent dans l'image source pour ce qui est de la déformation elle-même, mais copiera ce décalage inchangé dans l'image déformée. En résumé... Utilisez « [-distort](https://imagemagick.org/command-line-options/#distort) » pour que les résultats soient cartographiés dans une image de même taille. Et utilisez « [+distort](https://imagemagick.org/command-line-options/#distort) » pour tenter de définir automatiquement la taille de l'image de sortie, MAIS aussi pour utiliser et générer des décalages de canevas virtuel (attributs de page). Voir aussi Fenêtre de déformation (plus bas) si vous voulez outrepasser cette sélection générale de fenêtre et contrôler exactement quelle taille et quelle partie de l'image déformée vous voulez voir dans vos résultats.
Note... La fenêtre d'ajustement optimal générée par « [+distort](https://imagemagick.org/command-line-options/#distort) » est plus grande de 2 pixels que ce à quoi les utilisateurs s'attendraient généralement. La raison en est que ces pixels contiennent des pixels semi-transparents issus du filtre de rééchantillonnage par zone, et que ces pixels sont essentiels à la « jointure des bords » et à la superposition correctes de l'image déformée. Techniquement, le nombre de pixels ajoutés devrait dépendre de la mise à l'échelle en sortie du Support du filtre de rééchantillonnage. C'est-à-dire de l'ampleur avec laquelle la zone d'un pixel peut « s'étaler » à cause du filtre de rééchantillonnage. Cependant, comme la mise à l'échelle de chaque pixel peut être variable, le calcul du nombre absolument correct de pixels supplémentaires nécessaires est une affaire très délicate, et n'en vaut généralement pas la peine. Les 2 pixels ajoutés sont donc une « approximation », car les déformations agrandissent rarement les images, ce qui fait « s'étaler » davantage les pixels. De plus, comme la plupart des filtres de rééchantillonnage standard ont un support de 2 unités, l'ajout de 2 pixels est raisonnable. Et comme cet ajout est « fixe », il laisse aux utilisateurs la possibilité de simplement rogner la taille de l'image (de diverses manières), s'ils le souhaitent. L'« approximation » de 2 pixels devient manifestement trop petite lors d'agrandissements d'images. Mais ce sont là des déformations assez rares, et les utilisateurs peuvent définir leur propre Fenêtre (voir plus bas) si cela pose problème. Le décalage virtuel de l'image déformée sur le canevas virtuel est ajusté pour tenir compte de ces 2 pixels supplémentaires, de sorte que l'image déformée est correcte pour la superposition, mais pas pour une simple composition. Mais soyez averti que si le Recadrage et le Rognage préserveront l'emplacement de l'image superposée, le Rabotage et le Découpage décaleront l'image du calque par rapport à ce décalage.

Détermination de la couleur des pixels par la déformation

Comme évoqué ci-dessus dans Cartographie inverse des pixels, chaque point de l'image résultante est déterminé en cartographiant d'abord l'emplacement de ce pixel dans l'image de destination vers l'emplacement équivalent (déformé à rebours) dans l'image source, selon la méthode de déformation choisie. Cependant, la couleur finale du pixel n'est pas si simple à déterminer, car elle est affectée par un grand nombre de facteurs.

Pixels virtuels et mise en mosaïque

Le point cartographié par la déformation peut ne pas atteindre l'image source elle-même, mais tomber quelque part à côté, voire très loin de l'image réelle. La solution consiste à faire comme si l'image source était entourée d'une surface « infinie » ou « virtuelle », définie par le réglage « [-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) » courant. Pour les détails et des exemples de l'effet de ce réglage, voir les exemples de Pixel virtuel. Cela peut être très utile pour générer des motifs en mosaïque, déformés ou même non déformés, de l'image source. Les techniques pour cela sont présentées dans la section Pixel virtuel elle-même (non déformé), ainsi que dans Mise en mosaïque affine et Contempler des horizons lointains plus bas.

Pixels de déformation invalides

Parfois, la déformation d'un pixel de destination n'« atteint » même pas l'image virtuelle en mosaïque ! Cela se produit généralement lorsque vous déformez l'image à l'aide d'un type de méthode de déformation dans un espace tridimensionnel et que le « vecteur » du pixel n'atteint même pas le plan source dans lequel se trouve l'image. En gros, le résultat de la déformation devient mathématiquement « indéfini ». Dans ce cas, la couleur sera déterminée par le réglage « [-mattecolor](https://imagemagick.org/command-line-options/#mattecolor) ». Par exemple, lorsque vous voyez du « ciel » dans une Déformation en perspective (voir par exemple Contempler des horizons lointains), les mathématiques de détermination de l'emplacement dans l'image source sont devenues « indéfinies » (en fait, elles sont définies, mais ne sont pas valides du point de vue de la vision frontale de l'utilisateur). C'est pourquoi la « [-mattecolor](https://imagemagick.org/command-line-options/#mattecolor) » est produite en sortie pour le « ciel ». En réalité, l'algorithme de déformation en perspective parvient aussi à inclure certaines informations d'« anticrénelage » pour les pixels proches de l'horizon, bien que ce soit rare dans de telles situations.

Rééchantillonnage et filtres EWA

Une fois que vous savez où un pixel de destination « atteint » l'image source, vous devez déterminer la couleur à donner au pixel de destination, en utilisant les pixels proches du point « atteint » dans l'image source. Normalement, l'Opérateur de déformation utilise la méthode de Rééchantillonnage par zone EWA (Elliptical Weighted Average, moyenne pondérée elliptique) pour moyenner une zone plus vaste de l'image source afin de calculer la bonne couleur de ce pixel. Vous pouvez changer le filtre utilisé par le rééchantillonnage EWA à l'aide du réglage « [-filter](https://imagemagick.org/command-line-options/#resize) ». Voir Filtres de rééchantillonnage, et plus précisément Filtres cylindriques pour plus de détails. À l'origine, un filtre gaussien cylindrique était utilisé pour le rééchantillonnage EWA, car c'est ce qui était défini dans l'article de recherche d'origine sur le rééchantillonnage EWA. Mais il tend à produire un résultat très flou, tout en ne produisant pas d'effets de crénelage. C'était le filtre par défaut, avec un bug d'implémentation qui provoquait un flou extrême avant cette version (désormais corrigé). À partir de IM v6.6.5-0, à la suite de discussions majeures avec Nicolas Robidoux, professeur de mathématiques à l'Université Laurentienne, le filtre par défaut pour les déformations d'images a été remplacé par le filtre « **Robidoux** », un filtre cubique très « à la Mitchell », conçu spécifiquement pour le rééchantillonnage EWA. Voir Filtres cylindriques pour des informations sur celui-ci et d'autres filtres cylindriques. Notez cependant que toute fonction sous-jacente de filtre Sinc fenêtré est remplacée par la fonction de filtre Jinc fenêtré, plus circulaire. Ainsi, sélectionner un filtre « Lanczos » renverra un filtre « Jinc fenêtré par Jinc », plutôt qu'un filtre « Sinc fenêtré par Sinc ». Voir Filtres cylindriques Jinc fenêtré pour plus de détails. À NOTER : les fonctions « Sinc » ne sont PAS réellement utilisables comme fonction cylindrique, car l'interaction de la fonction avec les distances radiales sur une grille amène les poids du filtre à prendre une forme qui tend à s'annuler d'elle-même (somme des poids nulle) chaque fois qu'un nombre pair de « lobes » est utilisé. Cela l'amène à son tour à tenter de générer des couleurs quasi infinies lorsqu'il est utilisé avec un motif de « hachurage » en damier au niveau du pixel. En gros, l'EWA utilise des filtres de rééchantillonnage, à l'image de l'Opérateur de redimensionnement, et vous pouvez donc aussi modifier les filtres à l'aide des Options de filtre expertes spéciales. Le flou d'un filtre « Gaussian » et des filtres de type gaussien peut par exemple être contrôlé par le Réglage de flou du filtre. De même, vous pouvez utiliser le Réglage du support des lobes pour contrôler la taille et la puissance des filtres Jinc fenêtré, tels qu'un filtre « Lanczos ». | _Il existe un certain nombre de méthodes de déformation extrêmes, qui désactivent automatiquement le rééchantillonnage EWA et n'utilisent que la recherche interpolée plus directe.

Par exemple, la déformation Depolar produit des zones de rééchantillonnage en forme d'arcs de cercle qui ne conviennent pas très bien au rééchantillonnage « elliptique » (EWA). D'autres déformations comme Shepards rendent le calcul des « facteurs de mise à l'échelle » extrêmement difficile, bien qu'une future amélioration de l'opérateur de déformation puisse le rendre possible).

Une technique de Suréchantillonnage est recommandée pour ces méthodes de déformation, afin d'éviter de générer de sévères Artefacts de crénelage dans les zones de compression d'image (sous-échantillonnage) des résultats.

_
---|---

Échec du rééchantillonnage

Dans certaines situations particulières, l'ellipse de rééchantillonnage EWA peut échouer à « atteindre » un quelconque pixel réel dont elle pourrait tirer une moyenne pondérée. En gros, l'ellipse est si petite, ou si fine, qu'elle tombe entièrement entre tous les pixels de l'image. Et sans aucune couleur de pixel, elle ne peut pas générer de couleur pour l'image de sortie en ce point. C'est une situation extrême, généralement impossible à atteindre à moins de jouer avec les Réglages de filtre experts. Mais dans le cas improbable où aucun pixel n'est atteint, ou où la somme des poids du filtre vaut zéro, le rééchantillonnage échouera. IM se rabattra alors sur une simple recherche interpolée directe, exactement comme si vous désactiviez le filtrage EWA (voir ci-après). Si vous voulez vérifier si cela se produit, vous pouvez utiliser l'Interpolation en arrière-plan spéciale avec une couleur d'arrière-plan inhabituelle (comme « rouge ») afin de mettre en évidence de tels échecs de rééchantillonnage. Par exemple, je règle ici délibérément le support d'un filtre box trop petit, rendant ainsi l'ellipse de rééchantillonnage très petite. J'agrandis aussi beaucoup l'image pour que vous puissiez voir quelles parties « atteignent un pixel » et lesquelles non. |

  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]
Dans l'image fortement agrandie, le cercle de rééchantillonnage n'atteindra qu'un seul pixel (produisant un cercle crénelé de couleur unie), ou bien il ne correspondra à aucun pixel, car la zone d'échantillonnage circulaire tombe entièrement entre les pixels ; le filtre se rabattra alors sur un dégradé de couleur interpolé (Interpolation bilinéaire par défaut), afin d'obtenir au moins une couleur raisonnablement valide pour l'image résultante. Voici le même exemple, mais en remplaçant la méthode d'interpolation par l'Interpolation en arrière-plan spéciale (et normalement inutile) (qui renvoie simplement la couleur d'arrière-plan, réglée ici sur « gris »). |

  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]
Pour une couverture complète (de sorte qu'il trouve toujours au moins un pixel), un filtre de rééchantillonnage cylindrique a besoin d'un « support » d'au moins environ 0,707 (sqrt(2)/2) (valeur par défaut d'un filtre box). Tous les filtres sont généralement bien plus grands que cette taille de support minimale. Pour des exemples, voir la section sur les Filtres cylindriques. | _Les petits points colorés dans les coins sont dus à une optimisation du rééchantillonnage pour les pixels virtuels (abandon d'un coûteux rééchantillonnage EWA lors de l'échantillonnage de zones de pixels virtuels de couleur unie). Ils disparaîtront ou changeront avec un choix différent du réglage « [-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) ».

Normalement, ce n'est pas un problème, et on ne le voit ici que parce que distort utilise une « Fenêtre d'ajustement optimal » légèrement plus grande que l'image d'origine, et qui inclut donc quelques pixels supplémentaires autour du bord, échantillonnant dans ce cas des pixels virtuels.

_
---|---

Recherche de couleur interpolée ou directe

Vous pouvez utiliser « [-filter](https://imagemagick.org/command-line-options/#filter) point » pour désactiver le filtrage, et donc le rééchantillonnage EWA. Lorsque c'est fait, ImageMagick bascule les recherches de couleur vers l'Interpolation de pixel rapide et plus simple. C'est-à-dire qu'il recherchera une couleur en n'utilisant qu'une référence « ponctuelle » unique à l'image source, sans aucune « zone de rééchantillonnage ». La couleur des pixels résultants utilisera une couleur interpolée basée uniquement sur les plus proches voisins du point.

L'interpolation provoquera généralement de sévères effets de crénelage
lorsqu'une forme quelconque de minification ou de sous-échantillonnage de l'image se produit.

Mais elle fonctionne extrêmement bien pour les images ne contenant que des déformations minimales telles que rotations, mises en mosaïque, ou pour l'agrandissement d'image (grossissement ou suréchantillonnage). Une technique de Suréchantillonnage peut être combinée à l'interpolation pour améliorer les résultats dans les zones de forte compression, minification ou sous-échantillonnage. Voir Problèmes du cycle Depolar-Polar (une déformation qui ne peut pas utiliser le rééchantillonnage EWA) pour un exemple d'usage du suréchantillonnage afin de résoudre le crénelage interpolé.

Résumé détaillé de la déformation (verbose)

En définissant « [-verbose](https://imagemagick.org/command-line-options/#verbose) » avant d'exécuter « [-distort](https://imagemagick.org/command-line-options/#distort) » (utilisez « [+verbose](https://imagemagick.org/command-line-options/#verbose) » pour le désactiver de nouveau), distort produira sur le canal d'erreur standard des informations sur l'algorithme et les coefficients internes qu'il calcule et utilise pour déformer l'image donnée, de la manière spécifiée. Vous pouvez utiliser ces informations pour examiner et comprendre comment la déformation fonctionne et est appliquée. C'est aussi un outil de débogage que l'on peut utiliser pour comprendre ce qui ne va pas, ainsi que dans le cadre du processus d'implémentation de nouvelles déformations.

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

[IM Output] | | | [IM Text]

| [IM Output]

| NOTE : l'image résultante est presque, mais pas tout à fait exactement, identique à l'image d'entrée (voir « déformations neutres » ci-après).
---|---
La sortie verbose détaille les deux techniques de déformation alternatives pour la déformation donnée. L'une est une déformation « [AffineProjection](#affineprojection) », tandis que l'autre montre une alternative avec l'Opérateur FX à faire soi-même, détaillant exactement comment elle cartographie un pixel donné de l'image de sortie (i,j) vers une recherche interpolée dans l'image d'entrée (xx,yy), de façon à transformer l'image. Elle effectue le calcul de l'ellipse de rééchantillonnage, qui recourt à des mathématiques complexes (valeurs propres) ; elle ne calcule que le point de recherche interpolé non mis à l'échelle dans l'image source à partir duquel déterminer la couleur du pixel (i,j). Les deux donnent des informations sur le processus de déformation et peuvent servir à extraire des informations supplémentaires pour d'autres déformations du même type. Pour un exemple plus complexe d'usage de ces informations, voir Mécanismes internes de la perspective et Mécanismes internes du bilinéaire plus bas. Pour un exemple d'usage d'une commande FX pour la déformation d'image, voir aussi Redimensionnement d'image FX. Les additions et soustractions supplémentaires de « 0.5 » ci-dessus sont nécessaires pour convertir les « coordonnées de pixel » en « coordonnées d'image », et sont requises pour un traitement mathématique correct des déformations d'images. Voir Coordonnées d'image contre coordonnées de pixel plus bas.

Déformations neutres

L'exemple ci-dessus montre les résultats d'une déformation neutre. C'est-à-dire faire passer une image par distort (pour un effet secondaire quelconque) mais sans aucune déformation réelle (juste une cartographie 1 à 1 des pixels). Le filtre de rééchantillonnage EWA ne reproduira pas exactement les mêmes couleurs que l'original, mais floutera très légèrement les pixels individuels avec leurs voisins. Cela est dû au filtre bidimensionnel utilisé, et bien que ce flou de couleur soit minime, il ne peut jamais être éliminé. Pour réaliser une véritable déformation « neutre », il faut donc aussi désactiver le filtrage EWA et utiliser la Recherche de couleur interpolée ou directe (voir ci-dessus). |

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

[IM Output]
Presque tous les Réglages d'interpolation extrairont généralement une copie exacte du pixel source lorsqu'il est référencé exactement. Toutefois, par précaution, vous pouvez aussi spécifier l'interpolation Nearest-Neighbor, pour la rapidité et l'assurance que seule une correspondance de couleur exacte est renvoyée, indépendamment de toute erreur en virgule flottante que distort pourrait produire. |

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

[IM Output]
Cela peut sembler contre-productif, mais ce peut être une méthode très utile pour agrandir la zone d'une image, ou pour mettre des images en mosaïque (à l'aide des Méthodes de pixel virtuel), sans réellement redimensionner les données d'image d'origine. Voir Mise en mosaïque à l'aide des pixels virtuels via Distort pour des exemples. Autrement dit, on utilise l'Opérateur de déformation pour ses effets secondaires, tels que la mise en mosaïque multi-image par pixels virtuels, l'agrandissement ou le rognage de la taille d'image, l'ajout de bordures, voire la translation (par des quantités entières ou même sous-pixel). Rien de tout cela ne requiert réellement que l'image soit « déformée », juste « modifiée » d'une manière « programmée ».

Fenêtre : où regarde Distort

Comme mentionné ci-dessus, l'usage de « [-distort](https://imagemagick.org/command-line-options/#distort) » ou « [+distort](https://imagemagick.org/command-line-options/#distort) » change ce que seront la taille et l'emplacement résultants de l'« image de destination », à savoir respectivement : identiques à l'image source (en ignorant tout réglage de canevas virtuel), ou un calcul d'ajustement optimal pour l'image source déformée (si possible). Ces deux choses définissent en gros quelle partie de l'« espace déformé » résultant l'image de destination voit. Une autre façon de le concevoir est que l'image de destination est une « fenêtre » regardant l'image déformée résultante, ou une « fenêtre de visualisation » (viewport) sur l'espace déformé. Le réglage « distort:viewport » outrepasse ces deux valeurs par défaut et vous permet de spécifier directement quelle partie de l'espace déformé vous voulez voir...

[-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

Ceux-ci ont été ajoutés dans IM v6.3.6-1. Cela n'agrandit ni ne met à l'échelle l'image déformée, cela ne fait que spécifier l'emplacement et la zone visualisés (la fenêtre) dans l'espace de l'image déformée. On peut s'en servir pour créer une image de destination d'une taille précise, ou pour déplacer la vue vers une zone spécifique de l'espace de l'image déformée. C'est très semblable à l'usage du 'Recadrage par fenêtre' sur une image déformée de taille infinie (définie par les pixels virtuels). Par exemple, nous rognons ici la sortie sur la seule tête du koala (avec une déformation neutre). En d'autres termes, un simple « recadrage par fenêtre » direct de l'image d'origine non déformée. |

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

[IM Output]
Et ici, nous élargissons la vue pour examiner l'espace supplémentaire entourant l'image déformée, et montrer les effets qu'a le réglage Pixel virtuel sur l'espace infini entourant l'image source d'origine. |

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

[IM Output]
Dans ce cas, cela ressemble davantage à l'usage de l'Opérateur Extent pour agrandir l'image. Cependant, au lieu de simplement remplir avec la couleur d'arrière-plan, distort remplit la zone ajoutée selon le Réglage de pixel virtuel. Ici, avec le réglage de pixel virtuel « [Edge](misc.html#edge) » par défaut, ce qui produit les lignes horizontales et verticales de pixels, répliquées à partir des pixels le long du bord de l'image d'origine. Vous pourriez faire un meilleur choix pour le Réglage de pixel virtuel. Par exemple, l'usage d'un réglage « [Background](misc.html#background) » fera fonctionner cette déformation neutre à peu près exactement comme l'Opérateur Extent. Pour cette image, un réglage de pixel virtuel « [White](misc.html#white) » serait probablement un meilleur choix. |

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

[IM Output]
Le « [+repage](https://imagemagick.org/command-line-options/#repage) » final dans les exemples précédents est nécessaire pour supprimer le décalage de canevas virtuel de la fenêtre que « [-distort](https://imagemagick.org/command-line-options/#distort) » laissera en place lorsque le réglage de fenêtre est utilisé. Cette information n'est tout simplement pas souhaitée dans ce cas. Dans d'autres cas, comme lors de la superposition d'images déformées, vous voudriez conserver cette information de décalage. L'option de fenêtre est particulièrement utile avec un réglage de pixel virtuel « [Tile](misc.html#tile) » ou même « [Mirror](misc.html#mirror) », vous permettant de générer des images en mosaïque de n'importe quelle taille et dans différents styles. Vous pouvez même utiliser distort pour déformer ces images en mosaïque, comme illustré dans Mise en mosaïque affine plus bas. |

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

[IM Output]

Recadrage carré centré

Si vous utilisez l'option « [-set](https://imagemagick.org/command-line-options/#set) » pour définir la « fenêtre » de l'image résultante, vous pouvez inclure des échappements pour cent dans la valeur affectée. Plus précisément, vous pouvez inclure des échappements pour cent FX qui peuvent effectuer des calculs mathématiques. Cela signifie que la « fenêtre » peut être calculée, tout en exploitant les attributs, par exemple la taille de l'image courante en mémoire, pour spécifier la taille finale de l'image résultante. Qu'est-ce que cela veut dire ? Eh bien, cela veut dire que la « fenêtre » peut servir à générer des types spéciaux de Recadrage qui nécessitent normalement une ou plusieurs pré-lectures de l'image (ou une interface de programmation API plus avancée) et des calculs externes. Par exemple, vous pouvez rogner un « carré central » d'une image sans avoir besoin de connaître au préalable la taille ou l'orientation de l'image d'origine. C'est complexe, aussi j'ai placé l'expression de fenêtre dans des variables afin de la rendre plus facile à lire, à coder et à déboguer, bien qu'il s'agisse en réalité d'une simple expression constante (fixe).

  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]

L'image résultante est le plus grand carré centré que l'on puisse extraire de n'importe quelle image source, quelle que soit la taille de cette image. La distorsion elle-même ne déforme pas réellement l'image, elle ne fait que copier la zone couverte par la fenêtre d'affichage. Notez qu'il faut calculer les QUATRE nombres pour produire un « rognage carré centré », car toutes les valeurs dépendent de l'orientation de l'image. Ainsi chaque expression utilise un test d'« orientation de l'image » de la forme « w>h ? ... : ... », de sorte que la valeur résultante dépend de l'orientation de l'image. Voici une autre forme utilisant les fonctions « min() » et « max() » au lieu des tests d'orientation de l'image. |

  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]
Avec l'aimable autorisation de la page Tidbits de Fred Weinhaus. Une technique combinant plusieurs procédés de traitement d'image pour faire la même chose est présentée dans Vignettes, rembourrage et rognage carrés.

Rognage selon le rapport d'aspect

Cette technique peut être étendue pour rogner une image au centre afin de l'adapter à un rapport d'aspect donné. Voir aussi la discussion du forum Rogner selon le rapport d'aspect.

Autres exemples de fenêtre d'affichage

Voir aussi Méthodes de rotation des images ci-dessous pour d'autres exemples d'utilisation d'une fenêtre d'affichage afin de contrôler quelle partie de l'espace déformé est visible dans le résultat.

Mise à l'échelle de la sortie et suréchantillonnage

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

Ceci a été ajouté dans IM v6.4.2-6, comme facteur général de mise à l'échelle de l'image de sortie. Cela agrandit l'image de sortie du facteur donné et par conséquent « [-distort](https://imagemagick.org/command-line-options/#distort) » devra générer N2 fois plus d'« échantillons » de recherche déformés. Le nombre est généralement un entier, mais il peut aussi être un facteur d'agrandissement à virgule flottante. Notez que de nombreuses distorsions vous permettent également de « mettre à l'échelle » la taille de l'image déformée résultante ; cependant la taille de l'image résultante ne serait pas affectée par cette mise à l'échelle (sauf si un « [+distort](https://imagemagick.org/command-line-options/#distort) » « au meilleur ajustement » était utilisé). Ce réglage « scale » ne change toutefois en rien le contenu de l'image résultante, il ne fait qu'agrandir ou réduire l'image de sortie résultante. Cela peut par exemple servir, avec une « fenêtre d'affichage » appropriée, à produire une image que vous pouvez facilement « [-resize](https://imagemagick.org/command-line-options/#resize) » à une taille précise, ce qui permet de générer un « zoom » contrôlé dans l'image déformée, sans perte de qualité. Par exemple, nous « zoomons » sur la tête du koala. |

  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]
Notez que, bien que la fenêtre d'affichage ait été demandée à 44x44 pixels, l'image de sortie réelle a été mise à l'échelle à 110x110 pixels. Plus couramment, cela sert de moyen simple pour « suréchantillonner » (voir ci-dessus) l'opération de distorsion. Pour cela, on utilise un facteur d'échelle de « suréchantillonnage » entier, et après avoir déformé l'image on la remet à sa taille d'origine, pour fusionner les échantillons supplémentaires et produire un résultat de plus haute qualité. |

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

[IM Output]
De plus, comme le « rééchantillonnage de zone » n'est pas nécessaire lorsqu'on utilise le « suréchantillonnage » pour améliorer la qualité de l'image (il ne fait que le ralentir), on le désactive généralement en utilisant une option « [-filter](https://imagemagick.org/command-line-options/#filter) point » (voir la section précédente).


Introduction aux méthodes de distorsion

Distorsion Scale-Rotate-Translate (SRT)

L'une des distorsions les plus simples, mais probablement l'une des plus polyvalentes, est la distorsion « SRT » ou « Scale-Rotate-Translate » (SRT n'est qu'une abréviation pratique). Vous avez déjà vu l'exemple « sans effet » de cette distorsion dans les exemples ci-dessus, où l'image est traitée sans qu'aucune distorsion réelle ne lui soit appliquée, bien qu'elle soit tout de même filtrée, ce qui peut induire un très léger flou. Voici une répétition des résultats de la distorsion « sans effet » ci-dessus…

  magick koala.gif    -distort SRT 0    koala_noop.gif

[IM Output] [IM Output]

| _Notez que l'image sera très légèrement floutée du fait de l'utilisation durééchantillonnage de zone. Cependant les filtres de rééchantillonnage d'IM ont été délibérément conçus pour minimiser ce flou pour la distorsion « sans effet », et il est nécessaire pour un usage normal.

Si vous voulez une distorsion « sans effet » parfaite à des fins particulières, désactivez le rééchantillonnage EWA. C'est-à-dire, spécifiez le filtre « sans effet » « -filter Point » avant l'opérateur de distorsion.


---|---
La distorsion « SRT » est en réalité constituée de trois distorsions distinctes réunies dans une seule méthode de distorsion, c'est pourquoi on l'appelle distorsion « Scale-Rotate-Translate ». Tous les arguments, à l'exception de la rotation _angle
, sont facultatifs, ce qui rend les arguments très variables, selon exactement combien d'arguments séparés par des virgules ou des espaces vous fournissez, jusqu'à un maximum de 7 nombres à virgule flottante. **-distort SRT "** |

                  Angle

| **"** | -> rotation centrée
---|---|---|---

        Scale     Angle

| -> mise à l'échelle et rotation centrées

X,Y               Angle

| -> rotation autour de la coordonnée donnée

X,Y     Scale     Angle

| -> mise à l'échelle et rotation autour d'une coordonnée

X,Y ScaleX,ScaleY Angle

| -> idem

X,Y     Scale     Angle  NewX,NewY

| -> mise à l'échelle, rotation et translation de la coordonnée

X,Y ScaleX,ScaleY Angle  NewX,NewY

| -> idem
Ce que cela fait, c'est prendre une image que vous avez sélectionnée, et un point de contrôle facultatif. Si aucun point de contrôle n'est donné, le centre exact de l'image source est utilisé. Autour de ce point, la distorsion va, dans l'ordre… mettre à l'échelle l'image, la faire pivoter, puis translater ou déplacer le point de contrôle sélectionné vers une nouvelle position. D'où le nom de cette distorsion. L'ordre des arguments montré ci-dessus reflète l'ordre des opérations réellement appliquées à l'image. X,Y pour translater le « centre » des transformations vers l'origine, ScaleX,ScaleY l'image, Angle faire pivoter l'image, puis NewX,NewY translater le « centre » vers ces coordonnées. Autrement dit, l'opérateur représente en réalité 4 opérations de distorsion internes toutes appliquées simultanément comme une seule distorsion. Bien que, pour nous humains, seules 3 distorsions distinctes soient impliquées. Prenons donc un exemple simple en utilisant l'image « koala »… Un seul argument correspond simplement à une rotation autour du centre de l'image, produisant en gros un résultat similaire à l'ancien opérateur Rotate, mais sans aucune augmentation de la taille de l'image. |

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

[IM Output]
Notez que par défaut la taille de l'image d'entrée est aussi utilisée pour l'image de sortie, de sorte que l'image pivotée peut être rognée. Elle est aussi parfaitement centrée, que l'image ait un nombre pair ou impair de pixels. En utilisant la forme « plus » de « +distort » et un nettoyage des décalages du canevas virtuel résultant, nous pouvons générer quelque chose de très similaire à l'opérateur Rotate normal. |

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

[IM Output]
| Depuis IM 6.7.3-4, l'opérateur Rotate utilise désormais la distorsion Distort SRT. Avant cela, il utilisait les opérations de cisaillement, qui ne produisaient pas d'aussi bon résultat.
---|---
Réduisons-la aussi de 30 %, mais en utilisant un fond transparent. |

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

[IM Output]
Le jeu d'arguments suivant spécifie le « centre » autour duquel l'image est pivotée et mise à l'échelle. Ce point est appelé « point de contrôle » ou « poignée » dans l'image, c'est-à-dire un emplacement utilisé pour contrôler la distorsion. Comme nous utilisons un point précis pour cette distorsion, n'utilisons pas le mode « au meilleur ajustement » afin d'éviter les complications des « décalages virtuels ». Par exemple, faisons pivoter et mettons à l'échelle le koala autour de son « nez », qui se situe en 28,24 dans l'image source. Tant qu'à faire, déformons différemment les échelles X et Y. |

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

[IM Output]
Et comme dernier exemple, déplaçons aussi le « nez » vers le bas de l'image, et réglons le fond sur un blanc assorti. |

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

[IM Output]
Notez que la position finale est elle aussi une valeur à virgule flottante. En fait, tous les arguments peuvent être des valeurs à virgule flottante et la distorsion fera ce qu'il faut. Rappelez-vous que chacune des opérations, Scale, Rotate et Translate, est effectuée dans cet ordre. Comme vous pouvez le voir, cette distorsion est très polyvalente, et bien que vous puissiez la concevoir comme déformant l'image selon trois méthodes différentes en séquence, elle applique en réalité les trois distorsions simultanément pour produire le résultat montré. Cela la rend plus rapide que l'exécution de plusieurs opérateurs individuels, et produit généralement un meilleur résultat final. Ce qui précède illustre également l'utilisation de différents réglages de pixel virtuel pour définir la couleur employée pour les zones référencées hors de l'image source réelle. Pour voir l'effet de l'interpolation sur les rotations, voir Interpolation d'une ligne et d'un bord pivotés. Cette distorsion est spécialement conçue pour prendre une image et générer une animation basée sur les mouvements et la rotation de cet objet. Par exemple, je crée ici un vaisseau spatial stylisé, que j'anime ensuite de manière très sommaire. Le vaisseau repose sur sa base en 20,75 (pour la mise à l'échelle initiale de « tassement ») tandis que la « poignée » normale de déplacement et de rotation est le centre du vaisseau, situé en 20,60 dans l'image d'origine. Ces points représentent des points de contrôle grâce auxquels l'objet peut ensuite être animé en termes 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]

Bien sûr, c'est un exemple très sommaire de la façon dont vous pouvez utiliser une distorsion « [SRT](#srt) » pour animer une image statique, mais vous devriez saisir l'idée. Vous pouvez ajouter davantage d'images, et peut-être des flammes et de la fumée pour l'améliorer encore (contributions bienvenues, le meilleur résultat sera ajouté ici avec votre nom).

Méthodes de rotation des images

Les images peuvent être pivotées de bien des façons. Mais de simples rotations ne sont peut-être pas ce que vous recherchez. Faire pivoter une image sans changer sa taille… |

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

[IM Output]
Ou faire pivoter de manière à ne rogner aucune partie de l'image pivotée… |

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

[IM Output]
Cependant, en général, vous ne voulez pas voir le pixel virtuel « black » (ou toute autre couleur non issue de l'image) entourant l'image proprement dite. Une solution consiste à rogner l'image (à l'aide d'un réglage de fenêtre d'affichage de distorsion) au plus grand rectangle de même rapport d'aspect, de sorte qu'il ne contienne que des pixels réels de l'image résultant de la rotation. Cependant, calculer ce rectangle est plutôt délicat, et a fait l'objet de vives discussions sur le forum ImageMagick à l'aide de quelques équations trouvées sur le Math Help Forum. Ici, nous faisons pivoter et effectuons un rognage interne au plus proche possible du rapport d'aspect 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]
Cela paraît complexe, mais c'est parce qu'il faut en réalité calculer 4 valeurs distinctes pour définir le réglage de fenêtre d'affichage : la largeur, la hauteur et le décalage dans l'image d'origine. Une autre solution consiste non seulement à faire pivoter, mais aussi à mettre l'image légèrement à une plus grande échelle afin de « remplir » les limites de l'image d'origine. |

  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]
Cette dernière méthode est idéale pour une correction de rotation mineure des photos, car elle préserve la taille originale de l'image. La seule raison pour laquelle cette méthode est plus simple, c'est qu'il n'y a qu'une seule valeur d'« échelle » à calculer, et qu'elle peut donc être effectuée « en ligne ».

Distorsions utilisant des points de contrôle

Alors que la méthode de distorsion « [SRT](#srt) » se définit en spécifiant des angles de rotation et des facteurs d'échelle, la plupart des distorsions se définissent en déplaçant des « points » sur l'image source vers une nouvelle position dans l'image résultante. Cela ressemble un peu au déplacement du point « centre » lors de la définition d'une translation « [SRT](#srt) ». Ces points sont appelés points de contrôle, et se définissent plus habituellement en donnant 4 valeurs à virgule flottante (2 paires de coordonnées) pour chaque point de contrôle. Aussi une distorsion se définit-elle souvent en termes de plusieurs ensembles de 4 valeurs. Par exemple…

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

Où le point de contrôle Xi,Xi dans l'image source (relatif à son canevas virtuel) est mappé vers Ii,Ji dans l'image de destination déformée. Cependant, comme l'opérateur de distorsion mappe en réalité les coordonnées de destination vers les coordonnées source (voir Mappage inverse des pixels), l'usage interne de ce qui précède consiste à mapper les coordonnées I,J vers les coordonnées X,Y. Le résultat devrait néanmoins être le même, c'est juste une autre manière de penser.
Avant la version IM 6.3.6-0, lorsque l'opérateur de distorsion a été introduit pour la première fois, l'ordre des coordonnées des points de contrôle était défini comme toutes les coordonnées source, suivies de toutes les coordonnées de destination. Cela rendait toutefois très difficile de déterminer quelles coordonnées source et de destination se correspondaient, et ne permettait pas d'ajouter simplement d'autres points de contrôle pour affiner davantage une distorsion.
--- ---
Cela est défini ainsi afin que le mouvement de chaque point de contrôle individuel reste groupé dans la liste de valeurs à virgule flottante séparées par des virgules (ou des espaces). Cela permet aussi l'usage futur de « fichiers de points de contrôle » externes. La distorsion la plus simple utilisant des points de contrôle est la distorsion « [Affine](#affine) », bien que celle-ci, comme vous le verrez plus loin, se définisse généralement en termes de trois points, mais vous pouvez utiliser seulement un ou deux mouvements de point de contrôle. En réalité « [SRT](#srt) » est simplement un sous-ensemble à un ou deux points d'une distorsion « [Affine](#affine) ». Par exemple, ici nous déplaçons le « nez » de notre image de koala en « 28,24 » vers la nouvelle position « 45,40 » (indiquée par la flèche rouge), ce qui résulte en une simple « translation » de l'emplacement de l'image.
  magick koala.gif  -virtual-pixel white \
          -distort Affine '28,24 45,40'   koala_one_point.png

[IM Output] [IM Output]

Avec deux points, la distorsion « [Affine](#affine) » peut non seulement translater une image, mais aussi la mettre à l'échelle et la faire pivoter (toute la gamme d'une distorsion « [SRT](#srt) »). Par exemple, ici je mappe les « oreilles » du koala (la ligne rouge de « 30,11 » et « 48,29 ») vers une position horizontale plus large (une ligne bleue de « 15,15 » à « 60,15 »), ce qui oblige à mettre l'image à l'échelle, à la faire pivoter et à la translater pour que les points de contrôle soient déplacés vers cette nouvelle position.

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

Bien sûr, une distorsion « [SRT](#srt) » aurait pu reproduire la distorsion « [Affine](#affine) » à deux points ci-dessus, sauf qu'ici nous avons défini la distorsion d'une manière différente. La forme à utiliser dépend de vous, selon ce que vous cherchez à obtenir.

Coordonnées d'image contre coordonnées de pixel

L'utilisation des points de contrôle est simple dans le cas général, mais devient plus difficile lorsque vous devez aligner une image déformée avec une autre image ou avec des constructions dessinées. La raison en est que, tandis que la plupart des opérateurs d'IM traitent les coordonnées en termes de « positions de pixel » (par exemple lors du rognage, du dessin, etc.), les distorsions traitent les coordonnées en « coordonnées d'image » mathématiques. Ce dont il faut vous souvenir, c'est que les pixels d'une image ne sont pas un « point » mais en fait une « zone » d'une taille de 1 unité de pixel. C'est-à-dire qu'un pixel situé en 10,10 définit une zone carrée de couleur, allant de 10 unités vers le bas/en travers jusqu'à 11 unités vers le bas et en travers. En termes de coordonnées d'image, le centre du « pixel » se situe en réalité en 10.5,10.5. C'est-à-dire qu'il faut ajouter 0,5 lorsque vous déformez une image pour déplacer le centre d'un « pixel » vers un emplacement précis. Ainsi, pour repositionner les « pixels » de coin d'une image, vous devriez déplacer l'image en termes des pixels situés en 0.5,0,5 et _Width_ -0.5,_Height_ -0.5. En revanche, pour repositionner l'image en termes des « bords » réels de l'image, vous utiliseriez simplement les coordonnées 0.0,0,0 et _Width_ ,_Height_. Il vous suffit de réfléchir à ce que vous voulez réellement positionner, le centre des « pixels » de l'image ou les « bords » de l'image. Ou même de savoir si cela importe réellement pour votre problème particulier. Rappelez-vous que si vous voulez dessiner d'autres éléments sur votre image déformée, vous devrez donner les positions de dessin en termes de « positions de pixel ». Et oui, l'opérateur « -draw » peut dessiner des lignes, des cercles et d'autres formes en utilisant des valeurs à virgule flottante. De même, la largeur de trait et/ou les rayons des objets peuvent aussi être donnés en valeurs à virgule flottante. [IM Output] [IM Output]

| _Une largeur de trait de dessin inférieure à 1,0 ne fonctionne pas bien (voirDessin de lignes). De plus, le remplissage de zone ajoute un 0,5 supplémentaire (correspondant à l'ajout de la largeur de trait) aux bords de la zone de remplissage (voir Limites de remplissage Draw). Cela est fait quelle que soit la largeur de trait réellement utilisée.

Pour plus d'informations, voir Limites de remplissage Draw. Quelque chose que je considère comme un bogue._

Points de contrôle utilisant des échappements de pourcentage

Vous pouvez aussi utiliser des échappements de pourcentage dans les arguments de distorsion. Par exemple, vous pouvez extraire les attributs d'une image, puis les utiliser pour redimensionner une autre image afin qu'elle corresponde à la première. Ici, je récupère la taille de l'image intégrée « rose: », puis j'utilise une distorsion « [Affine](#affine) » pour redimensionner l'image « logo: » plus grande à la même taille (sans préserver le rapport d'aspect). |

   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]
Notez que distort génère une « image en couches » légèrement plus grande sur un canevas virtuel (y compris un décalage négatif), ce qui explique pourquoi j'ai dû inclure un « [+repage](https://imagemagick.org/command-line-options/#repage) » dans l'exemple ci-dessus. Elle aura également des bords flous, car distort génère une distorsion exacte ou véritable de l'image, et non une image redimensionnée orthogonale nettoyée. Pour des exemples plus avancés d'utilisation de l'opérateur de distorsion afin de redimensionner des images, exactement comme le fait l'opérateur Resize, voir Distort contre Resize, ainsi que la méthode Distort Resize ci-dessous. Vous pouvez aussi utiliser des échappements de pourcentage pour calculer des distorsions en fonction de la position d'une image dans la liste d'images courante. Des exemples en sont donnés dans Distorsions animées.

Ajustement des points de contrôle par les moindres carrés

Si vous fournissez plus de 3 points de contrôle pour une distorsion « [Affine](#affine) », ou plus de 4 points pour les distorsions « [Perspective](#perspective) » ou « [Bilinear](#bilinear) », ImageMagick effectuera une moyenne par les moindres carrés sur tous les points donnés pour trouver une représentation « moyenne » de ces distorsions. Cela signifie que si vous essayez de faire correspondre une image avec une autre image (une technique connue sous le nom de « recalage d'image »), vous pouvez définir plus que le nombre minimal de points nécessaires afin que le résultat soit une distorsion plus précise. Bien sûr, si un ou plusieurs de ces points ne « collent » pas bien avec les autres points, alors le résultat sera faussé par le point « aberrant », car IM essaie de trouver le meilleur ajustement en utilisant tous les points de contrôle donnés, y compris le mauvais. Une vérification pour trouver et supprimer les « mauvaises paires de coordonnées » peut être nécessaire dans certaines situations.

Points de contrôle à partir de fichiers

La liste de nombres (arguments) d'une distorsion peut aussi être lue à partir d'un fichier en utilisant une syntaxe « @filename », tout comme vous pouvez saisir du texte pour des choses telles que « [-annotate](https://imagemagick.org/command-line-options/#annotate) » et « [label:](text.html#label) » (voir Caractères d'échappement dans les arguments texte). Par exemple, vous pouvez spécifier une distorsion comme ceci…

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

Le nom de fichier peut être simplement « @- » pour signifier lire le fichier depuis l'entrée standard. Le fichier lui-même sera lu comme une chaîne et traité comme la liste de coordonnées (arguments) nécessaires à la distorsion concernée. Comme les nombres peuvent être séparés par des virgules ou des espaces, cela signifie que les paires de coordonnées peuvent être proprement ordonnées à raison d'une paire de coordonnées par ligne, sous la forme…

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

Cela, combiné à l'ajustement par les moindres carrés, rend l'usage du recalage d'image très pratique. Comme le fichier n'est qu'une liste de quatre nombres par ligne, vous pouvez utiliser d'autres outils de script de traitement de texte tels que « cut », « paste », « column », ainsi que des outils de script de traitement de texte plus avancés tels que « sed », « awk », « perl », etc., pour manipuler les coordonnées. L'utilisation de fichiers de coordonnées et d'arguments de distorsion deviendra plus importante avec des distorsions plus avancées, telles que la distorsion « [Shepards](#shepards) », et les distorsions futures prévues « Grid » et « Mesh » où des centaines de paires de coordonnées peuvent être impliquées.


Méthodes de distorsion affine (à trois points)

Distorsion affine

La distorsion « [SRT](#srt) », ainsi que les formes à un et deux points de la distorsion « Affine » montrées ci-dessus, sont en réalité des simplifications d'une forme complète à 3 points de la distorsion « Affine ». En fait, si vous étudiez la sortie « -verbose » de n'importe quelle distorsion « [SRT](#srt) » (voir réglage de distorsion verbeux pour un exemple), vous constaterez qu'en interne il s'agit réellement d'une distorsion « [AffineProjection](#affine_projection) » (voir ci-dessous). Le seul effet de distorsion que les méthodes ci-dessus ne pouvaient pas gérer complètement était les « cisaillements » similaires à ce que fournirait l'opérateur Shear. Pour cela, vous devez utiliser une distorsion affine à trois points. Vous pouvez la concevoir comme une distorsion à trois points, en imaginant le premier mappage de coordonnées comme une « origine » et les deux autres mappages de coordonnées comme des vecteurs partant de cette origine. Par exemple, ici je dessine du texte, et je superpose un « vecteur » rouge et un bleu pour définir les trois points de contrôle relatifs à ce texte. Maintenant, en déplaçant les coordonnées (en tant que coordonnées d'image) de ces deux lignes, nous pouvons translater, faire pivoter, mettre à l'échelle et cisailler cette image de texte, pour l'adapter au nouvel emplacement de ces lignes.

  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]

Dans le premier exemple, seule la troisième coordonnée (celle de la ligne rouge verticale) a été modifiée, provoquant le cisaillement de l'image et son étirement le long de l'axe Y. Bien sûr, cela n'a pas à se limiter au seul axe Y. Les exemples ultérieurs apportent des changements plus radicaux à l'image, y compris des rotations et des translations. Bien entendu, l'opérateur Annotate Text peut lui aussi incliner du texte réel de la même manière, mais uniquement en modifiant l'angle. Cet opérateur ne mettra pas le texte à l'échelle ni ne l'agrandira dans une direction particulière. C'est-à-dire qu'il peut faire pivoter un « vecteur » mais ne peut pas l'étirer plus long ou plus court. Voir Utilisation des arguments d'Annotate pour un tableau d'exemples. La distorsion affine peut réaliser ce type de distorsion pour n'importe quelle image, et pas seulement du texte dessiné. Affine utilisant moins ou plus de trois paires de coordonnées Si seulement 1 ou 2 paires de points de contrôle sont fournies, IM utilisera une forme plus limitée de distorsion affine pour correspondre au mouvement de ces points moins nombreux. Par exemple, avec une seule paire de coordonnées, il se limite à des translations non mises à l'échelle de l'image. Avec 2 points, il se limitera à des distorsions « [Scale-Rotate-Translation](#srt) » (sans cisaillements). Voir la discussion précédente sur les Distorsions utilisant des points de contrôle pour des exemples. Si plus de 3 points de contrôle sont donnés à une distorsion « [Affine](#affine) », alors IM utilisera l'ajustement par les moindres carrés pour trouver la meilleure distorsion affine « à 3 points » correspondant à toutes les paires de coordonnées données. Cela signifie que les points de contrôle de l'image source peuvent ne pas se mapper exactement sur les points de contrôle de l'image de destination, mais sur une « moyenne » au meilleur ajustement de tous les points donnés. Par exemple, si vous avez le scan d'un document, vous pourriez localiser et mapper les 4 coins du document pour une distorsion affine afin de corriger la rotation et la mise à l'échelle du document. De cette façon, vous pouvez obtenir un meilleur ajustement « moyen » basé sur 4 points plutôt que 3. Notez que si davantage de coordonnées peuvent produire une distorsion meilleure et plus précise, si une paire de coordonnées est très mauvaise, l'ajustement par les moindres carrés peut ne pas produire un bon ajustement du tout. Une vérification pour éliminer les « mauvaises paires de coordonnées » peut être nécessaire. 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.

Distorsion par projection affine (Affine Projection)

Comme je l'ai déjà mentionné, les divers arguments d'une distorsion « [SRT](#srt) » et les points de contrôle d'une distorsion « [Affine](#affine) » sont mathématiquement transformés en 6 nombres particuliers qui représentent les « coefficients » d'une « Affine Projection ». Ces nombres de la projection affine sont les coefficients utilisés pour le mappage direct des points de l'image source vers l'image de destination. C'est-à-dire qu'ils sont les valeurs mathématiques utilisées pour mapper un x,y de l'image source vers un i,j de l'image de destination. Les 6 arguments à virgule flottante sont (dans l'ordre où ils doivent être donnés)…

sx, rx, ry, sy, tx, ty

Ceux-ci forment à leur tour les expressions de distorsion… Xd = | sx*Xs + ry*Ys + tx | , | Yd = | rx*Xs + sy*Ys + ty |
---|---|---|---|---|---
Où « Xs,Ys » sont les coordonnées de l'image source et « Xd,Yd » les coordonnées de l'image de destination. En interne, ImageMagick Distort inversera les équations ci-dessus afin d'effectuer le mappage de pixels approprié pour mapper les coordonnées « Xd,Yd » vers la recherche de la couleur en « Xs,Ys » dans l'image source. Pour plus d'informations sur la façon dont les diverses valeurs de la matrice de projection affine affectent l'image, voir la sous-page Transformations par matrice affine. Si vous avez déjà ces coefficients précalculés (par exemple extraits de la sortie verbeuse de distort, ou calculés vous-même par d'autres méthodes à partir d'autres formes d'arguments d'entrée), alors vous pouvez les fournir directement à IM pour déformer l'image. Par exemple, ici je « cisaille » l'image mais en utilisant un angle pour calculer les coefficients, plutôt que le mouvement de points de contrôle. |

   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]
L'ancienne façon de réaliser cette distorsion dans ImageMagick consistait à employer le couple d'opérateurs "-affine" et "-transform". Cependant, depuis IM v6.4.2-8, ce n'est plus qu'un simple appel à 'AffineProjection' au moyen de la forme 'plus' ou 'bestfit' de l'opérateur de distorsion. Voir la sous-page Transformations par matrice affine pour plus de détails.

Exemples de distorsion affine

Pavage affine

Les trois méthodes de distorsion de type affine que nous avons examinées jusqu'ici offrent aussi des façons intéressantes de générer divers motifs de pavage, à partir d'une image distordue.

  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]

Utiliser ainsi un mappage de distorsion est en fait exactement la manière dont fonctionne le 'plaquage de texture' (texture mapping) dans les bibliothèques graphiques 3D et les jeux. La seule différence est qu'ils mappent les coordonnées tridimensionnelles de surfaces vers une image bidimensionnelle. Même la distorsion 'nulle' ("-distort SRT 0"), avec une fenêtre de distorsion appropriée, fournit un moyen utile de paver une séquence entière d'images, telles que les tuiles de paillettes animées.

  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]

Notez que j'ai aussi utilisé un "[-filter](https://imagemagick.org/command-line-options/#filter) point" pour désactiver le rééchantillonnage EWA, afin d'accélérer l'opération et de garantir une copie parfaite (non échantillonnée) des pixels de l'image source. La fenêtre de distorsion peut aussi spécifier un décalage, de manière à 'faire défiler' les images pavées sur l'image résultante.

Cubes 3D, par superposition affine

La distorsion '[Affine](#affine)', avec ses points de contrôle, est idéale pour générer des cubes en projection orthographique ou isométrique (voir sur Wikipedia, Projection orthographique et Projection isométrique pour les définitions), à partir de trois images. Tout ce que vous avez à faire est de déterminer quatre points de contrôle sur une image de destination. Comme nous allons employer une technique de superposition d'images, les points peuvent même prendre des valeurs négatives, ce qui permet à IM d'ajuster en conséquence la taille finale de l'image d'après les images déformées générées. Pour cet exemple, je choisirai le point de contrôle '0,0' pour le centre du cube, et trois points répartis à intervalles égaux autour de ce point central, à '-87,-50', '87,-50' et '0,100'. Il ne me reste alors qu'à mapper les coins appropriés de trois images (de préférence carrées) vers ces points de contrôle. |

  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]
Notez que j'ai utilisé les coordonnées des bords réels de l'image lors de sa distorsion. Cela signifie, en termes mathématiques, que les images devraient s'emboîter exactement. Notez aussi que je n'ai pas simplement 'composé' les images ensemble (au moyen de la composition alpha Over par défaut). Si vous procédiez ainsi, vous obtiendriez de légers 'interstices' transparents entre les images. La bonne méthode (comme montré) consiste à utiliser la composition alpha Plus pour joindre des pièces 'reliées par leur bord', ce qui donne une jonction parfaite sans interstices transparents. Pour plus d'informations, voir Aligner deux images masquées. Ensuite, j'ai ajouté une bordure supplémentaire et supprimé toute transparence. Ce n'est pas obligatoire, et vous pourriez tout aussi bien utiliser n'importe quel arrière-plan (ou "none"), mais cela mettrait en évidence tout 'interstice' présent dans vos images.
[IM Output] On voit à droite un agrandissement d'une de ces jonctions dans l'image, montrant l'absence de tout interstice 'rempli de noir' le long de la jonction. Une méthode alternative pour créer un cube isométrique, sans employer "-distort", est présentée dans Cube isométrique par cisaillements. Cependant, cette technique ne permet pas d'utiliser des coordonnées sous-pixel (non que j'en aie utilisé ci-dessus, mais j'aurais pu) ; elle est restreinte au positionnement des images au moyen de coordonnées en pixels entiers.

Ombres 3D, par cisaillements affines

Les mêmes méthodes de superposition employées ci-dessus peuvent aussi servir à générer de superbes ombres tridimensionnelles de formes irrégulières. Cela ajoute l'ombre de n'importe quelle forme 'plate' se tenant à la verticale. Par exemple, créons une forme dotée d'une base plate, afin qu'elle puisse éventuellement tenir debout. |

  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]
Notez que la 'forme' possède une base plate qui est aussi la dernière ligne de l'image. C'est important, car nous allons déformer la forme le long de cette ligne, de sorte que l'ombre se raccorde à la forme debout le long de cette ligne. Voici la commande qui génère l'ombre 3D à partir de cette 'forme debout' |

  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]
Ce qui précède réalise pas mal d'étapes pour aboutir au résultat montré. La plus délicate est cependant la première ligne. Elle retourne l'image, puis la remet en place par un 'retournement par distorsion'. Le résultat est que la ligne du bas est désormais placée de façon à avoir une valeur Y=0 sur le canevas virtuel. Autrement dit, l'image entière a reçu un décalage négatif qui la positionne de sorte que la ligne du bas passe par l'origine du canevas virtuel. Grâce à cette 'astuce', nous pouvons appliquer un 'cisaillement affine' très simple à l'ombre extraite pour la déformer. Nous n'avons donc pas besoin de connaître la taille de l'image de la forme pour déformer l'ombre, tout en parvenant à garder l'ensemble 'aligné', puisque tout reste synchronisé le long de la ligne du bas (Y=0) de l'image d'origine. Vous pouvez ajuster la direction dans laquelle tombe l'ombre et sa longueur simplement en ajustant la coordonnée finale ('100,50') du 'cisaillement affine'. Les deux premières 'paires de coordonnées' ne doivent pas être modifiées, car elles 'verrouillent' l'ombre sur l'image d'origine le long de la ligne du bas. Notez toutefois que jusqu'à la toute dernière étape, toutes les images comportent des décalages négatifs de canevas virtuel ; la prudence est donc de mise si vous prévoyez d'afficher ou d'enregistrer les images de traitement intermédiaires. Le seul problème de cet effet d'ombre est qu'il s'agit d'un 'flou uniforme'. Autrement dit, l'ombre n'est pas réaliste. En réalité, l'ombre devrait être nette là où elle rejoint la 'forme debout' et devenir plus floue à mesure qu'elle s'en éloigne. Cela peut cependant se faire au moyen d'un mappage de flou variable, tel qu'utilisé dans Police d'ombre floue selon la distance.

Ombre 3D, par compression en perspective

Voici une autre façon d'ajouter un flou variable à l'ombre. Je ne la recommande pas vraiment, mais elle est assez simple à mettre en œuvre. Cet exemple a été développé avant que le mappage de flou variable ne soit ajouté à ImageMagick. En gros, on déforme d'abord la forme d'ombre initiale au moyen d'une distorsion en perspective (examinée en détail plus bas), de manière à comprimer fortement la 'partie éloignée' de l'ombre, la rendant floue, puis on étend cette compression en la déformant vers sa position finale de 'cisaillement affine' que nous avons utilisée plus haut. |

  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]
Ceci est presque exactement identique à l'exemple d'ombre 3D d'origine, mais avec quelques étapes supplémentaires. La forme d'origine est d'abord déformée en trapèze, puis tout espace excédentaire est rogné pour accélérer l'étape suivante. Nous extrayons ensuite une ombre floue de la forme déformée. Une fois l'image d'ombre créée à partir de l'image déformée, les mêmes points de contrôle servent à annuler la distorsion de l'image d'ombre et à la déplacer vers sa position sous forme de cisaillement affine. La clé est que le flou de l'ombre s'applique à une image déformée, dont la distorsion est ensuite annulée (et, dans ce cas, cisaillée en affine en même temps). Par conséquent, le flou est lui aussi déformé et étendu, de manière à flouter davantage autour de la partie supérieure de l'ombre, et bien moins le long de la ligne de base. Grâce au flou en perspective, on obtient un flou variable qui devrait culminer à environ 100 pixels de la ligne de base au sol. Cela est déterminé par les points de contrôle du flou en perspective initial.

Redimensionner des images au moyen de Distort

Distort et Resize sont en réalité très semblables à bien des égards. Ce sont tous deux des opérateurs de distorsion d'image, et tous deux utilisent le mappage inverse des pixels pour créer l'image résultante. Tous deux exploitent aussi le réglage "[-filter](https://imagemagick.org/command-line-options/#resize)" et ses contrôles avancés pour déterminer la couleur, quoique de manière très différente. Resize est une opération de distorsion d'image simplifiée (et bien plus courante), qui permet de nombreuses optimisations. Elle est alignée orthogonalement, ce qui permet d'utiliser une méthode de filtrage d'image orthogonale en deux passes lors du redimensionnement. Autrement dit, elle redimensionne d'abord dans une dimension, puis dans l'autre, au moyen d'une image temporaire intermédiaire. De plus, comme le facteur d'échelle est constant sur toute l'image de destination, avec des bords alignés sur une dimension en pixels entiers, l'algorithme peut grandement simplifier son traitement ainsi que les besoins de mise en cache du filtre qu'il emploie. Toutes ces limitations autorisent diverses optimisations qui la rendent très rapide comparée au travail que doit accomplir distort. Distort peut lui aussi redimensionner des images, mais il le fait en une seule passe, qui convertit directement l'image d'origine en la nouvelle image résultante. Il n'a pas besoin d'aligner les bords sur des positions de pixels entières, et pourrait pivoter et mettre à l'échelle chaque position de pixel. En d'autres termes, c'est un opérateur bien plus général, qui l'oblige à effectuer beaucoup de traitement supplémentaire pour chaque pixel du résultat final, avec moins de possibilités d'optimisation. Pour que Distort produise une image équivalente à celle de Resize, il doit suivre exactement les mêmes limitations et employer quelques astuces complexes de traitement d'image. Cela a été discuté sur les forums IM, dans Redimensionnement correct (au moyen de distort), et a abouti à une technique de redimensionnement par distort équivalente, fondée sur l'usage de la méthode de distorsion affine. La méthode de distorsion 'Resize ' qui en résulte a été ajoutée à ImageMagick version 6.6.9-2. La version en ligne de commande (CLI) de cette distorsion accepte et traite exactement le même argument de géométrie que Resize, y compris le léger écart des facteurs d'échelle pour les deux dimensions, ce qui en fait une alternative directe au redimensionnement. |

  magick logo:  -distort Resize 150x  logo_resized.png

[IM Output]
| _Les autres interfaces API vers la méthode de distorsion 'Resize ' n'accepteront que deux nombres comme arguments, traités comme la taille entière finale de l'image résultante. Pour l'instant, elles n'accepteront pas un véritable argument de géométrie avec ses divers indicateurs de contrôle du redimensionnement, qui modifient la taille finale de l'image. Autrement dit, des indicateurs tels que le pourcentage, l'agrandissement/réduction seul, voire la préservation du rapport d'aspect ne sont pas disponibles.

Il appartient aux mainteneurs de ces API d'ajouter une telle prise en charge pour cette méthode particulière de distorsion d'image._
---|---
La véritable différence entre le Distort Resize ci-dessus et l'opérateur Resize normal est que la version par distort utilise un filtre cylindrique (elliptique) à une seule passe, bien plus lent, pour déterminer la couleur finale de chaque pixel. En d'autres termes, cela fournit une comparaison directe entre des filtres orthogonaux en deux passes (resize) et un filtre cylindrique bidimensionnel en une seule passe (distort resize). Voir Distort vs Resize pour un exemple de cette comparaison.

Les rouages internes de Distort Resize

Ce qui suit correspond aux opérations équivalentes que le Distort Resize ci-dessus a effectuées en interne.

  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

Les valeurs '150' et '113' (utilisées à deux endroits) correspondent à la taille souhaitée de l'image finale, arrondie à l'entier le plus proche. Elles ont été calculées de façon à préserver au mieux le rapport d'aspect de l'image, tout en respectant la limitation de taille entière finale. Elles sont normalement calculées par ImageMagick à partir de l'argument de géométrie de redimensionnement fourni, au moyen d'une fonction API distincte. Il active ensuite la transparence et les pixels virtuels transparents, afin que les 'pixels virtuels' externes ne participent pas au calcul de la couleur finale du pixel. Une fois la distorsion achevée, la transparence est de nouveau supprimée (désactivée), et les pixels de 'tampon' ajoutés par distort sont retirés au moyen d'un rognage d'image. En raison de l'usage de pixels transparents, la commande ci-dessus ne fonctionnera correctement que pour des images ne contenant aucune transparence, comme l'image intégrée "logo:" utilisée en exemple ci-dessus. Voici la version bien plus complexe, requise pour séparer les effets des pixels virtuels de toute transparence éventuellement présente dans l'image.

  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

Cela réalise deux distorsions : d'abord pour déformer l'image, puis pour déformer séparément le canal alpha (transparence), en utilisant dans chaque cas transparent pour éliminer les effets des pixels virtuels. Par conséquent, c'est au moins deux fois plus lent que lorsqu'aucune transparence n'est présente dans l'image d'origine. Ces deux techniques sont implémentées en interne par la méthode Distort Resize. À ce titre, cette 'méthode' est en réalité une 'macro' pratique pour les utilisateurs, et non une véritable méthode de distorsion à part entière, laquelle est une distorsion 'affine'.


Méthodes de distorsion à quatre points

Distorsion en perspective

Le type de distorsion le plus souvent demandé est probablement une opération rapide de distorsion en perspective. C'est une distorsion à 4 points, qui requiert donc au moins 4 jeux de paires de points de contrôle, soit 16 valeurs à virgule flottante. Par exemple, j'ai ici l'image d'un bâtiment. À partir de cette image, j'ai repéré manuellement l'emplacement de 4 points (rouges). J'ai aussi défini l'emplacement final vers lequel ces points sont transformés dans l'image finale (bleus), de manière à 'redresser' ou 'rectifier' la façade du bâtiment.

  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]

Pour réaliser la distorsion d'image proprement dite, il vous suffit de fournir ces coordonnées à la méthode '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]

Remarquez la zone vierge en haut à droite, là où la distorsion a 'manqué' les données de pixels de l'image source. Ce que fait IM dans cette situation est déterminé par le réglage "-virtual-pixel" (voir Pixel virtuel). Ce qui est moins visible, c'est qu'une petite partie du bord le plus à gauche de l'image d'origine est également 'perdue' pour la même raison. À titre indicatif, inversons aussi la distorsion, en permutant les coordonnées de chaque paire de mappage. Cela nous permet de voir à quel point l'image est dégradée par la distorsion.

  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]

Pas mal. Un bon 'flou' est présent, mais on n'y peut rien. Remarquez que le 'flou' est pire du côté droit de l'image, là où elle a été le plus comprimée. Toutes les distorsions souffrent de ce problème de compression ; c'est pourquoi vous devriez toujours essayer de déformer à partir d'une image d'origine, plutôt que de déformer une image déjà déformée. Voici un autre exemple d'utilisation de cette transformation, au moyen de l'image de test en damier spéciale créée plus haut, que nous déformons puis dont nous inversons la distorsion.

  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]

On voit le léger flou causé par la compression de l'image, mais l'image est pour l'essentiel restaurée. Ce qui se passe réellement, c'est qu'IM utilise toutes les paires de points de contrôle fournies pour calculer les coefficients appropriés d'une '[Projection en perspective](#perspectiveprojection)' (voir la section suivante). Si vous incluez un réglage Verbose, vous pourrez voir à la fois les coefficients et l'équivalent FX à réaliser soi-même utilisé en interne par IM pour effectuer cette distorsion. Si 3 paires de points de contrôle ou moins sont fournies, IM se rabattra automatiquement sur la distorsion '[Affine](#affine)' plus simple. Tandis que plus de 4 points (pour le 'recalage d'images ') seront ajustés par moindres carrés afin de trouver la distorsion la mieux adaptée à tous les points de contrôle fournis. À VENIR : Alternative. Les quatre coordonnées pourraient aussi représenter un triangle et un point central. Vous pouvez fixer le triangle et déplacer le point central, ou fixer ce centre et déplacer les trois autres coordonnées, pour générer la vue en perspective. Si vous souhaitez voir plus en détail comment fonctionne la distorsion, consultez les Rouages internes de la perspective ci-dessous. Vous pouvez aussi consulter une implémentation en Postscript présentée dans un article PDF, Rectification en perspective, par Gernot Hoffmann. Jetez également un œil aux Transformations affines et en perspective de Leptonica.

Contempler des horizons lointains

Vous pouvez produire des effets très inhabituels au moyen des distorsions en perspective si vous ajustez les coordonnées pour produire un 'point de fuite' à l'intérieur des limites de l'image. |

  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]
Nous avons donc utilisé 'Green' pour les pixels virtuels qui 'entourent' l'image d'origine, ce que nous avons activé au moyen des réglages d'arrière-plan des pixels virtuels. Mais ce qui est plus intéressant, c'est l'apparition de la couleur 'blue' définie au moyen du réglage "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)". Cette couleur 'blue' représente une zone où les pixels générés par la distorsion sont invalides , et dans ces zones, l'opérateur "-distort" se contentera d'afficher le réglage "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)". Pour une distorsion en perspective, tout pixel aboutissant dans le 'ciel' de l'image résultante sera classé comme invalide. De plus, elle définit le 'ciel' comme étant le côté de l''horizon' sur lequel l'image source n'apparaîtra pas. Le 'ciel' n'apparaîtra dans les images distordues en perspective que lorsque l'image résultante est fortement raccourcie par la distorsion. Si vous ne voulez pas de 'ciel' dans le résultat final, la meilleure idée est de régler "[-background](https://imagemagick.org/command-line-options/#background)" et "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" sur la même couleur. La distorsion en perspective devient plus intéressante lorsqu'on emploie l'un des réglages spéciaux de pixel virtuel à pavage infini. Par exemple, nous avons utilisé ici un réglage '[tile](misc.html#tile)' pour générer un plan pavé à l'infini. |

  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]
Un mot d'avertissement au sujet de cette image. Demander une image pavée à l'infini est très lent à générer. Plus l'image est grande, plus c'est lent. Vous pouvez suivre la progression de "[-distort](https://imagemagick.org/command-line-options/#distort)" (ou de toute autre tâche lente de traitement d'image) au moyen du réglage de contrôle opérationnel "[-monitor](https://imagemagick.org/command-line-options/#monitor)". En gros, pour un seul pixel proche de l'horizon, ImageMagick devra moyenner un nombre énorme de pixels de l'image d'origine afin de déterminer la couleur appropriée. Cela peut prendre très longtemps. ImageMagick s'efforce bien de limiter le temps qu'il consacre à traiter ces pixels proches de l'horizon, en mettant des informations en cache et en s'appuyant sur une connaissance intégrée de divers réglages de pixel virtuel, mais cela peut tout de même prendre longtemps. Pour plus de détails sur cette méthode, voir Rééchantillonnage par zone plus haut. Une autre image en perspective pavée à l'infini peut être générée au moyen d'un réglage de pixel virtuel aléatoire… |

  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]
Ce qui se passe, c'est que tous les pixels virtuels entourant l'image sont simplement des choix aléatoires de n'importe quel pixel au sein de l'image elle-même. Le résultat est un sol constitué d'un bruit aléatoire qui devient plus lisse et plus flou à mesure que le regard se porte vers l'horizon de l'image. Cela donne une sensation naturelle de profondeur, sans aucun motif répétitif spécifique. J'ai repris ici l'exemple ci-dessus, mais avec une image source en noir et blanc pur. Cependant, ce n'est pas l'image distordue proprement dite qui m'intéresse, mais seulement le motif 'random' de pixel virtuel qui a été généré ; j'ai donc changé la partie de l''espace de l'image distordue' que j'observe, en utilisant un réglage spécial '-set option:distort:viewport'. Ce réglage remplace la taille et l'emplacement habituels de la zone de l'espace distordu observée. Dans ce cas, une zone ne contenant que des pixels virtuels, et non l'image distordue. |

  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]
Pour compléter l'image, j'ai supprimé le décalage de la fenêtre (au moyen de "[+repage](https://imagemagick.org/command-line-options/#repage)" ), et j'ai placé en dessous, ou DstOver, un dégradé de couleurs de coucher de soleil dans le 'ciel' transparent (défini au moyen de "[alpha setmattecolor](https://imagemagick.org/command-line-options/#mattecolor)") . Une image très intéressante qui pourrait servir de toile de fond pour d'autres travaux de traitement d'image. Vous pouvez ajuster les paramètres de distorsion pour régler la hauteur et l'inclinaison de l'horizon. Voici un test plus traditionnel d'une distorsion en perspective avec pavage. |

  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]
Dans mes études, j'ai constaté que le test ci-dessus est trompeur, car il ne donne aucune indication réelle de la qualité de la technique de rééchantillonnage par zone pour des échelles proches de l'unité d'une image (zone de premier plan, plutôt que zones lointaines). C'est-à-dire un examen attentif des problèmes de rééchantillonnage tels que décrits dans Artefacts de rééchantillonnage. Cette dernière image montre aussi un point de 'coupure' proche de l'horizon où ImageMagick a décidé qu'il ne valait pas la peine d'essayer de déterminer la couleur appropriée d'un pixel (en tenant compte du réglage de pixel virtuel courant), mais court-circuite l'algorithme EWA et utilise la couleur moyenne de l'image entière. Cela n'est visible dans cette image qu'en raison du motif diagonal de couleur à grande échelle qui y est présent. La couleur moyenne d'une image n'est calculée qu'une seule fois par opération de distorsion, et seulement lorsqu'elle est nécessaire pour la première fois. En l'utilisant, ImageMagick économise énormément de temps dans le calcul des couleurs proches de l'horizon, puisqu'en général le résultat sera la couleur moyenne de l'image. Cela se produit lorsque, soit l'ellipse devient si allongée qu'elle dépasse les limites de la virgule flottante, soit le nombre de pixels d'échantillonnage (parallélogramme englobant de l'ellipse) devient plus de 4 fois supérieur à l'image source d'entrée. Ceci n'est actuellement pas réglable par l'utilisateur.

Boîtes 3D, superposition en perspective

La forme 'plus' de "+distort", qui garantit que l'image distordue entière est conservée dans une couche (ou 'canevas virtuel') correctement positionnée, est conçue de sorte que si les mêmes 'points de contrôle' servent à déformer des images, ces points s'aligneront dans l''espace virtuel'. Cela signifie que si les images sont fusionnées en couches, elles s'aligneront elles aussi d'après les points de contrôle. Par exemple, nous générons ici deux images, une image de 'face' et une image de 'dos', de sorte que deux points de contrôle de bord s'alignent l'un avec l'autre, pour former le dos d'une boîte.

  # Générer une image de dos
  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

  # générer la couverture avant
  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

  # Déformer les deux images et fusionner au moyen des points communs.
  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]

Notez également l'usage de la composition alpha Plus pour joindre des pièces 'reliées par leur bord'. Cela est requis pour empêcher la génération d'un 'interstice semi-transparent' entre les deux images. Pour plus d'informations, voir l'exemple du cube 3D ci-dessus, ainsi que Aligner deux images masquées. Utiliser de telles positions signifie que presque toute l'image de 'dos' est en fait déformée vers une position 'x' négative. L'image résultante possède donc un décalage négatif sur le canevas virtuel. IM n'a aucun problème à faire cela lorsqu'on utilise la version par superposition "+distort" de l'opérateur. L'opérateur Layers Merge est lui aussi conçu pour gérer la superposition d'images à décalages négatifs, 'cousant' proprement les deux images ensemble. Je dois encore utiliser un "+repage" final pour retirer ce décalage négatif de l'image finale, une fois qu'elles ont été 'fusionnées' ensemble. Sinon, d'autres programmes tels que les navigateurs web risqueraient de ne pas comprendre ces décalages négatifs et de produire des effets indéfinis. L'exemple ci-dessus a également été placé dans le script shell "[box_set_example](../static/img/scripts/box_set_example) " afin que vous puissiez le télécharger et l'expérimenter plus commodément. Vous pouvez aller plus loin et ajouter aussi des images en miroir de la 'boîte' se reflétant sur la surface sur laquelle elle repose, même si vous voudrez peut-être recolorer ou atténuer cette image d'une manière ou d'une autre pour la rendre plus réaliste. Voir Reflets pour de telles techniques de miroir.
Un autre exemple, en PHP, a été développé lors d'une discussion sur l'enroulement de 'photos' autour d'un cadre de canevas sans bord. Voir Transformation d'enroulement sur canevas pour plus de détails.
Pour finir, voici un exemple fantastique de Jean-François Hren pour www.animecoversfan.com, qui a été abondamment discuté sur les forums de discussion IM.

[Diagram]

Cette image a été créée en prenant une image artistique de la jaquette d'un boîtier de vidéo d'animé, en découpant cette jaquette en 3 segments ('couverture', 'dos' et 'arrière'), en déformant chacun séparément en images superposées, en ajoutant une quatrième image de 'disque', puis en fusionnant le tout. L'image a ensuite été finalisée par l'ajout d'effets de reflets et d'ombrage (au moyen de la composition d'image HardLight), ainsi que par l'ajout d'effets de bordure et d'ombre semi-transparente (au moyen de CopyOpacity). Ce qui est plus étonnant encore, c'est que tout le processus a été réalisé par une seule commande "magick", à partir des images d'entrée. C'est un excellent exemple de ce dont IM est capable, et du processus par lequel un script de commande complexe peut être généré. Je recommande de lire la discussion du forum, car elle contient de nombreuses astuces, conseils et techniques générales de débogage. (D'autres exemples contribués sont les bienvenus)

Distorsion par projection en perspective (Perspective Projection)

Tout comme la distorsion '[Affine](#affine)' peut être traitée directement en fournissant les coefficients mathématiques d'une '[Projection affine](#affine_projection)', la distorsion '[Perspective](#perspective)' peut de même être traitée au moyen de 8 coefficients d'une distorsion 'Perspective Projection'. Comme précédemment, ces nombres représentent les coefficients utilisés pour le mappage direct des points de l'image source vers l'image de destination. Autrement dit, ce sont les valeurs mathématiques employées pour mapper un point x,y de l'image source vers un point i,j de l'image de destination. Les 8 arguments à virgule flottante sont (dans l'ordre donné)… sx, ry, tx, rx, sy, ty, px, py


Ces valeurs de coefficients forment à leur tour l'expression… Xd = | sx*Xs + ry*Ys + tx | , | Yd = | rx*Xs + sy*Ys + ty |
---|---|---|---|---|---


|


px*Xs + py*Ys + 1.0 | px*Xs + py*Ys + 1.0
Où "Xs,Ys" sont les coordonnées de l'image source et "Xd,Yd" les coordonnées de l'image de destination. En interne, ImageMagick Distort inversera les équations ci-dessus afin d'effectuer le mappage inverse des pixels approprié, mappant les coordonnées "Xd,Yd" pour rechercher la couleur en "Xs,Ys" dans l'image source. Les 6 premières valeurs de la 'Perspective Projection' sont en fait les mêmes coefficients que ceux de la '[Projection affine](#affine_projection)', quoique légèrement réordonnés pour être plus logiques (en termes de 'calcul matriciel', les 6 premiers éléments ont été transposés diagonalement). Les deux arguments supplémentaires px,py forment un diviseur d'échelle appliqué à l'ensemble de la distorsion, qui fait paraître l'image plus petite dans la direction spécifique déterminée par les valeurs fournies, donnant ainsi à l'image distordue l'effet de 'distance' de la perspective. Si ces deux valeurs sont mises à zéro, la distorsion 'Perspective Projection' devient équivalente à une 'Projection affine' Par exemple… |

  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]
N'oubliez pas que la matrice que vous fournissez est la matrice de projection directe, qui mappera les coordonnées de l'image source vers les coordonnées de l'image de destination. En interne, ImageMagick inversera la matrice afin de pouvoir mapper les coordonnées de l'image de destination vers les coordonnées de l'image source. Si vous souhaitez voir quelles sont ces valeurs, utilisez l'option de distorsion Verbose, pour faire afficher par IM ses coefficients internes sous forme d'une expression d'opérateur FX (voir la section suivante).

Les rouages internes de la perspective

Si vous ajoutez "-verbose" (voir Résumé de distorsion verbeux plus haut) juste avant la distorsion en perspective, IM affichera deux opérateurs qui devraient être des remplacements quasi équivalents de l'opérateur "-distort". L'un est une version "-fx" TRÈS LENTE (voir Opérateur FX à réaliser soi-même. L'autre sera la matrice Perspective_Projection de mappage direct. Par exemple… |

  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]


La première section Perspective Projection peut servir à mapper les coordonnées source vers les coordonnées de destination. La formule est celle donnée ci-dessus.

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 )


Un exemple d'extraction et d'utilisation de ces valeurs est présenté dans le dernier jeu d'exemples de Positionnement d'images de calques distordues. En revanche, la seconde section d'équivalent FX utilise un jeu différent de 8 coefficients, qui réalise le Mappage inverse de pixels qu'une distorsion d'image doit réellement appliquer. À savoir…

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 )


Notez que dans la formule équivalent FX en sortie, les coefficients du diviseur sont utilisés en premier car ils sont communs aux équations des coordonnées X et Y. Rappelez-vous que toutes les coordonnées que vous fournissez sont des coordonnées d'image, et non des coordonnées de pixel ; voir Coordonnées d'image contre coordonnées de pixel pour les détails. Ainsi, toute position de pixel devra se voir ajouter 0,5 à la coordonnée de pixel d'entrée avant d'appliquer ce qui précède, puis on soustrait 0,5 de la coordonnée finale pour la reconvertir en coordonnée de pixel (de dessin). Vous pouvez voir cela appliqué dans le code équivalent FX ci-dessus. Le test final de l'équivalent FX, juste avant la consultation de l'image source, traite les pixels « ciel » invalides, où la destination ne parvient pas à se mapper correctement sur l'image source. Cependant, il se contente de substituer 'blue' à ces pixels au lieu du "-mattecolor", et ne fournit aucun anticrénelage de l'horizon que l'algorithme interne fournit pour la distorsion en perspective.
Exemple de mappage direct en perspective… Ces mappages vous permettent de convertir une coordonnée précise d'une image vers un emplacement de l'autre image (dans les deux sens). Par exemple, un point sombre au centre de l'image source de la rose se trouve aux coordonnées de pixel '39,20'. En le convertissant en coordonnées d'image par ajout de ½, on obtient '39.5,20.5'. Nous pouvons maintenant utiliser les équations x,y vers i,j pour le mapper vers les coordonnées d'image de destination '44.2,24.1'. Et enfin vers les coordonnées de pixel « de dessin » en soustrayant ½, on obtient la position finale '43.7,23.6'. Et ici je marque cette coordonnée à l'aide d'un cercle, sur l'image d'entrée comme sur l'image de sortie…

  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]

Comme vous pouvez le voir, le même point dans l'image distordue en perspective a été correctement localisé dans les deux images (jusqu'au niveau sous-pixel) !

Distorsions bilinéaires

Les méthodes de distorsion 'Bilinear' implémentent un autre type de distorsion à 4 points. Cependant, celle-ci n'est pas aussi simple que la distorsion '[Perspective](#perspective)' que nous avons examinée ci-dessus. Mais, comme vous le verrez, c'est une distorsion alternative très utile.

Distorsion bilinéaire directe

Par exemple, prenons une image de test spéciale d'un mandrill sur laquelle une grille a été superposée, et distordons-la avec la perspective et le bilinéaire.

  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]
Bilinéaire
---|---|---|---

Vous devriez d'abord remarquer que les deux distorsions ont correctement mappé l'image d'un jeu de points de contrôle vers l'autre jeu de points. De plus, toutes les lignes horizontales et verticales de l'image source restent également droites, dans les deux distorsions. Cependant, les similitudes s'arrêtent là. La perspective réduit l'espacement entre les lignes de sorte que même les lignes diagonales restent droites. Il en résulte que l'aire des carrés devient plus petite, donnant ainsi au coin supérieur droit un aspect réaliste « au loin ». Le bilinéaire, en revanche, ne donne pas à un côté de l'image un aspect « plus lointain » et ne tente pas non plus de garder les lignes droites. Ce qu'il tente de faire, c'est de maintenir constants tous les espacements entre les lignes, mais cela a pour résultat de courber la ligne diagonale. Autrement dit, il préserve les rapports de distance le long de toute ligne donnée. C'est-à-dire que les longueurs relatives de chaque segment de ligne restent identiques sur toute la longueur de la ligne, même si la ligne elle-même peut être pliée, courbée ou raccourcie dans son ensemble. Cela signifie que l'espacement de la grille dans l'exemple ci-dessus reste à une échelle constante sur toute l'image, et que le carré distordu en haut à droite fait toujours à peu près la même taille que le carré distordu en bas à gauche. L'image conserve un aspect « plat », simplement distordue en une forme différente. Notez que le bilinéaire (direct) garantit bien que toute ligne horizontale ou verticale de l'image d'origine restera droite dans l'image finale. C'est-à-dire qu'il prendra un rectangle aligné orthogonalement et le transformera en le quadrilatère spécifié, de sorte que chacun des côtés du rectangle d'origine reste droit avec une échelle constante sur toute la ligne. C'est cet aspect de la distorsion qui rend une distorsion 'BilinearForward' utile dans des distorsions de « grille » bien plus complexes. En effet, deux « quadrilatères » voisins, même s'ils peuvent être distordus de manière très différente, s'aligneront toujours correctement bord à bord. Voici une autre comparaison entre '[Perspective](#perspective)' et '[BilinearForward](#bilinear_forward)', en utilisant une distorsion très sévère de l'image intégrée de la rose…

  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]
Bilinéaire
---|---|---|---

Pour atteindre ses objectifs (préserver toutes les lignes droites), la distorsion en perspective semble « aspirer » presque toute l'image dans la plus petite zone à droite, tandis que la distorsion bilinéaire a gardé la rose centrée, centrée dans son résultat. Là encore, elle a préservé les rapports de distance, gardant la rose également espacée entre les bords gauche et droit. Tout ce qu'elle a fait, c'est simplement compresser verticalement la hauteur de l'image de façon linéaire sur toute sa longueur. Cet aspect d'une distorsion 'BilinearForward' lui vaut aussi d'être appelée distorsion « trapézoïdale ». C'est-à-dire simplement compresser l'image de façon linéaire dans une direction, lorsqu'une seule direction est mise à l'échelle. Cette direction de compression peut même être inclinée, plutôt qu'alignée sur un axe. | _Notez qu'en raison de la complexité du mappage inverse de pixels nécessaire pour réaliser une distorsion 'BilinearForward', le rééchantillonnage de zone est actuellement désactivé.

Ainsi, les zones de compression extrême (d'un facteur supérieur à 2) présenteront probablement quelques effets de crénelage (voir les bords des lignes dans les exemples ci-dessus). Cependant, l'utilisation du suréchantillonnage ou de '-interpolate Spline' peut servir à améliorer la qualité de l'image finale.
---|---
| _Avant IM v6.5.7-0, la distorsion 'BilinearForward' était encore en développement et présentait des problèmes avec certains cas « dégénérés », pouvant provoquer une image d'erreur « noire » dans des situations spécifiques.

---|---

Distorsion bilinéaire inverse

Comme seules les lignes horizontales et verticales restent droites, vous ne pouvez pas utiliser une distorsion 'BilinearForward' pour inverser la distorsion. Comme les lignes de grille de l'image transformée ne sont plus horizontales ni verticales, elles ne resteront plus droites dans l'image résultante ! Par exemple, échanger les paires de coordonnées et réappliquer la distorsion « directe » (comme nous l'avons fait avec la distorsion '[Perspective](#perspective)' ci-dessus) ne parviendra pas à restaurer l'image d'origine.

  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]

Notez que les coordonnées réellement spécifiées se sont bien positionnées correctement, mais que la distorsion de l'image n'a pas été inversée. En résumé, une distorsion '[BilinearForward](#bilinear_forward)' n'est PAS son propre inverse. Pour restaurer l'image, vous devez utiliser une distorsion légèrement différente mais étroitement liée. L'inverse mathématique de la « transformation géométrique » a été implémenté sous la forme d'une distorsion 'BilinearReverse'. Par exemple…

  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]

| Comme indiqué précédemment, en raison de la complexité d'une distorsion '[BilinearForward](#bilinear_forward)', le rééchantillonnage de zone est actuellement désactivé, ce qui provoque ci-dessus de graves effets de crénelage.
---|---
La distorsion '[BilinearReverse](#bilinear_reverse)' possède les mêmes propriétés de préservation des rapports de distance qu'une 'BilinearFoward', mais convertit tout quadrilatère en un rectangle aligné orthogonalement, garantissant que les côtés du quadrilatère restent droits une fois mappés sur un alignement vertical et horizontal. Comme vous le voyez ci-dessus. | Avant IM v6.5.1-2, la distorsion 'BilinearReverse' était simplement implémentée sous le nom 'Bilinear'.
---|---
Certaines implémentations d'une distorsion bilinéaire (y compris les anciennes versions d'IM et la bibliothèque Leptonica) n'implémentaient que la version plus simple (inverse) de la distorsion bilinéaire ci-dessus. Cependant, une telle distorsion n'est pas très adaptée au « mappage direct » d'une image rectangulaire. Par exemple, ici j'essaie d'utiliser une '[BilinearReverse](#bilinear_reverse)' pour une distorsion qui aurait probablement dû utiliser une distorsion '[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]

Comme vous pouvez le voir, le quadrilatère de destination n'étant pas un rectangle orthogonal, l'image a été sévèrement distordue, produisant de nombreuses lignes courbées vers l'intérieur.

Distorsions bilinéaires en mosaïque

Or, si une '[BilinearReverse](#bilinear_reverse)' produit des images « courbées » à partir d'images rectangulaires, cet effet produit d'intéressants motifs de mosaïque qui semblent générer des surfaces courbes d'aspect tridimensionnel. Par exemple, en appliquant la même transformation que celle utilisée pour Observer des horizons lointains ci-dessus, on obtient ce résultat intéressant. |

  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]
En réalité, une '[BilinearReverse](#bilinear_reverse)' ne produira jamais d'« horizon » (pixels invalides). En revanche, l'utilisation de '[BilinearForward](#bilinear_forward)' tend à produire du « ciel » ou des « pixels invalides » (remplis avec le "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" courant) assez régulièrement. En fait, le motif de mosaïque tend à devenir plutôt délirant… |

  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]
| Comme indiqué précédemment, en raison de la complexité d'une distorsion '[BilinearForward](#bilinear_forward)', le rééchantillonnage de zone est actuellement désactivé, ce qui provoque ci-dessus de graves effets de crénelage.
---|---
C'est pourquoi je ne recommande pas d'utiliser une forme en mosaïque de '[BilinearForward](#bilinear_forward)'. Je vous recommande toutefois de définir un "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" approprié lorsque vous utilisez la distorsion directe, afin d'éviter l'apparition de plaques grises inattendues de « ciel ».

Fonctionnement interne du bilinéaire

La formule réelle pour mapper une coordonnée de l'image source vers une image de destination à l'aide d'une distorsion bilinéaire à mappage direct est… Xd = C0*Xs + C1*Ys + C2*Xs*Ys + C3 , Yd = C4*Xs + C5*Ys + C6*Xs*Ys + C7
Cependant, comme IM implémente les distorsions à l'aide de la technique du mappage inverse de pixels, la formule ci-dessus doit être inversée. C'est un processus complexe qui nécessite la résolution d'une équation quadratique, des racines carrées et toute une page d'algèbre. Si vous demandez à IM de sortir l'équivalent FX en mode Verbeux, vous verrez cette complexité. Par exemple, en utilisant l'image checks créée précédemment…
  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]


Le contrôle '(rt > 0 ) ? red :' dans la dernière ligne de l''équivalent FX ' sert à éviter une racine carrée négative invalide. C'est ce contrôle qui crée l'effet de « ciel » montré dans les exemples précédents. En revanche, comme la distorsion bilinéaire inverse est bien plus simple, on peut appliquer directement l'équation polynomiale plus simple pour inverser la distorsion précédente… |

  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]


Comme vous pouvez le voir, les équations résultantes sont très simples, car nous les appliquons désormais pour effectuer un mappage inverse de pixels des coordonnées de destination vers les coordonnées de l'image source. Les effets de crénelage vus ci-dessus sont causés par la distorsion '[BilinearForward](#bilinear_forward)', et non par la distorsion '[BilinearReverse](#bilinear_reverse)'. Cela vient du fait que le rééchantillonnage de zone est actuellement désactivé pour la version à mappage « direct » en raison de sa complexité.
Pour aller plus loin, je vous oriente vers Transformations affines et en perspective de Leptonica.

Distorsion bilinéaire combinée

En construction

Les deux méthodes de distorsion bilinéaire, utilisées ensemble, vous permettront de distordre directement N'IMPORTE QUEL quadrilatère en n'importe quel autre quadrilatère, tout en gardant les côtés du quadrilatère droits. Essentiellement, vous pouvez d'abord distordre en mode « Reverse » un quadrilatère en une image rectangulaire, puis distordre en mode « Forward » ce rectangle en le quadrilatère final. Ce type de distorsion signifie aussi que vous pouvez prendre n'importe quelle grille rectangulaire de coordonnées et la distordre en une autre grille rectangulaire de coordonnées. C'est ce qu'on appelle une distorsion « de grille ». Cette technique est la base principale du morphing d'images, où l'on définit une grille rectangulaire de lignes sur deux images et où on l'utilise pour fusionner les images en un composite intermédiaire, voire pour générer une animation qui morphe correctement d'une image vers une autre. Ceci n'a toutefois pas encore été implémenté, mais est un ajout prévu.


Distorsion polynomiale (distorsions à l'aide d'un ajustement polynomial)

La distorsion 'Polynomial', comme la plupart des méthodes de distorsion précédentes, mappe également des paires de points de contrôle, mais utilise une équation polynomiale standard. Cela signifie qu'un argument supplémentaire est nécessaire avant que les points de contrôle ne soient fournis.

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

L'argument 'Order ' est généralement un entier à partir de '1', bien qu'une valeur spéciale de '1.5' puisse aussi être utilisée. Il définit l'« ordre », c'est-à-dire la complexité de l'équation mathématique bidimensionnelle (utilisant à la fois 'x' et 'y') qui sera appliquée. Par exemple, un polynôme d'ordre '1' ajustera une équation de la forme… Xd = | C2x*Xs + C1x*Ys + C0x | , | Yd = | C2y*Xs + C1y*Ys + C0y |
---|---|---|---|---|---
Si vous la comparez avec l'équation utilisée pour la projection affine, vous constaterez qu'elle est équivalente. Comme 3 constantes sont nécessaires pour chaque formule X et Y, vous devez aussi fournir au moins 3 paires de coordonnées X,Y. Toute paire supplémentaire fera que l'équation sera ajustée aux moindres carrés sur les coordonnées données. L'« ordre » suivant, ou '1.5', est équivalent à une '[BilinearReverse](#bilinear_reverse)' (rappelez-vous que l'équation sert à mapper les coordonnées de destination vers l'image source). Xd = | C3x*Xs*Ys + C2x*Xs + C1x*Ys + C0x | , | Yd = | C3x*Xs*Ys + C2y*Xs + C1y*Ys + C0y |
---|---|---|---|---|---
Tout comme la distorsion '[BilinearReverse](#bilinear_reverse)', elle nécessite un minimum de 4 coordonnées. Par exemple… Fondamentalement, c'est exactement identique aux équations d'ordre '1' mais avec 1 terme supplémentaire ajouté aux équations polynomiales. Autrement dit, comme chaque équation a désormais 4 termes par axe, avec 4 constantes, il vous faut donc au moins 4 paires de coordonnées pour permettre à IM de déterminer ces 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]

Avec un ordre '2', les équations polynomiales sont développées davantage pour devenir un ajustement quadratique complet, nécessitant un minimum de 6 paires de coordonnées. 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
Fondamentalement, c'est exactement identique aux équations d'ordre '1' mais avec 3 termes supplémentaires (ordre 2 + 1) ajoutés en tête des équations polynomiales. Autrement dit, comme chaque équation a désormais 6 termes avec 6 constantes, il vous faut au moins 6 coordonnées pour permettre à IM de déterminer ces constantes. Chaque ordre polynomial successif au-delà de celui-ci ajoute 'order'+1 termes supplémentaires à chacune des deux équations de la paire. Ainsi, un polynôme à ajustement cubique d'ordre '3' nécessite un minimum de 10 paires de coordonnées pour être pleinement défini, et un polynôme à ajustement quintique d'ordre '4' nécessite 15 paires de coordonnées. Vous pouvez utiliser un résumé de distorsion verbeux pour voir l'équation résultante que la distorsion polynomiale a ajustée aux coordonnées spécifiées. Comme exemple plus important, j'ai une image d'une grille. J'ai aussi un grand jeu de coordonnées (stocké dans le fichier "[grid16_control_points.txt](../static/img/images/grid16_control_points.txt)") indiquant comment je veux déformer cette grille. J'ai ensuite demandé à IM de générer un polynôme cubique pour « au mieux ajuster » (best-fit) les coordonnées d'entrée.
  # déformer l'image
  magick grid16.png -virtual-pixel gray \
          -distort polynomial "3 $(cat grid16_control_points.txt)" \
          grid16_polynomial.png

  # inverser l'ordre des coordonnées de l'image
  awk '{print $3, $4, $1, $2}' grid16_control_points.txt \
                             > grid16_cp_inverse.txt

  # déformer l'image à nouveau pour revenir en arrière
  magick grid16_polynomial.png -virtual-pixel gray \
          -distort polynomial "3 $(cat grid16_cp_inverse.txt)" \
          grid16_restored.png

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

Le petit script "awk" prend le jeu original de paires de points de contrôle X,Y et en inverse l'ordre, afin que nous puissions ensuite utiliser le nouveau fichier pour tenter d'« annuler » la distorsion. | _Les coordonnées du fichier de points de contrôle "[grid16_control_points.txt](../static/img/images/grid16_control_points.txt)" sont des coordonnées d'image, ce qui signifie que chaque nombre désigne le centre du pixel auquel il se réfère. Sans le 0,5 supplémentaire, les valeurs seraient des « coordonnées de pixel » entières. Voir Coordonnées d'image contre coordonnées de pixel ci-dessus.

Les valeurs ont été déterminées uniquement par consultation manuelle à l'aide d'une visionneuse d'images, et de ce fait ne sont pas vraiment très exactes. Cela pourrait être à l'origine d'une partie des artefacts de distorsion inverse, bien que l'« ajustement optimal » fonctionnel des équations polynomiales ait dû réduire les effets de distorsion globaux.


---|---
Cela montre que si une distorsion polynomiale fonctionne, et fonctionne bien, ce n'est pas une distorsion exacte ni réversible. Essentiellement, les 81 coordonnées sont « moyennées » ensemble afin de générer un « ajustement optimal » mathématique des coordonnées d'entrée. Comme davantage de points de contrôle (81) ont été fournis que le minimum requis (10), aucun des points de contrôle n'est garanti de correspondre exactement aux coordonnées demandées. Cependant, pour cet exemple précis, où les coordonnées sont proches du résultat de distorsion attendu, cela devrait être raisonnablement proche. La fonction polynomiale aura généralement le plus d'erreurs le long des bords, et surtout dans les coins de l'image. Cela affecte non seulement les emplacements des pixels mais aussi la zone d'échantillonnage (EWA) sur les bords. C'est un résultat naturel de l'approximation utilisée. Un polynôme d'ordre supérieur aurait pu être utilisé, mais dans ce cas cela n'apporte pas de grandes améliorations. Dans ce cas précis, le polynôme tente en réalité de s'ajuster à une fonction trigonométrique non polynomiale. En raison de la nature de ces fonctions, la seconde distorsion sera plus imprécise que la première. Cet exemple est en fait très étroitement lié à la méthode radiale de distorsion en barillet que nous examinerons ci-dessous. Notez toutefois que les coordonnées mappées n'ont pas réellement besoin d'être disposées en grille, mais peuvent constituer n'importe quel jeu de mappage de coordonnées. Pour cette raison, elle est souvent utilisée par les géographes pour aligner (et superposer) des photos aériennes avec des cartes géophysiques, en utilisant comme points de contrôle des emplacements connus de villes, de carrefours, de sommets de montagnes et d'autres repères. | _Comme la distorsion polynomiale est généralement non réversible, il n'est pas possible pour IM de calculer l'« ajustement optimal » de la fenêtre d'affichage de l'image de destination pour l'image source donnée. Ainsi, la forme "[+distort](#distort_bestfit)" de l'opérateur ne fonctionne pas, et revient à une opération "[-distort](https://imagemagick.org/command-line-options/#distort)" normale. Vous pouvez toutefois toujours utiliser l'option Fenêtre d'affichage de distorsion pour définir la fenêtre d'affichage de l'image de destination.

---|---


Méthodes de distorsion circulaire et radiale

Ce sont des distorsions qui impliquent l'utilisation de vecteurs radiaux comme composant majeur du processus de distorsion.

Distorsion Arc (courber les images en arcs de cercle)

La distorsion 'Arc' (à partir d'IM v6.3.5-5) est une variante simple d'une distorsion polaire bien plus complexe (voir ci-dessous). Par défaut, elle courbe l'image donnée en un arc parfaitement circulaire sur l'angle indiqué, et sans autres arguments elle tentera de préserver autant que possible l'échelle de la ligne médiane horizontale de l'image ainsi que le rapport hauteur/largeur de l'image. Pour cela, elle prend jusqu'à quatre arguments.

_arc_angle rotate_angle top_radius bottom_radius_

Toutefois, seul l'argument "_arc_angle_" est requis, les autres arguments sont facultatifs et peuvent être ajoutés au besoin, dans l'ordre donné. Par exemple, appliquer 'Arc' à une image sur un angle de 60 degrés… |

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

[IM Output]
| _Notez que, contrairement aux autres opérateurs de distorsion d'image, une distorsion 'Arc' définira toujours la taille de l'image résultante de sorte que l'image source complète soit présente. Cela inclut les pixels de bord anticrénelés. Ainsi, l'image résultante correspondra rarement à la taille de l'image d'entrée.

Seules les options de fenêtre d'affichage de distorsion vous permettront de modifier la taille de l'image résultante pour une distorsion donnée._
---|---
L'ajout du second argument "_rotate_agle_" vous permet de faire pivoter l'image autour du cercle. Par exemple, la faire pivoter de 90 degrés. |

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

[IM Output]
Comme aucun argument de rayon spécifique n'a été mentionné, la méthode de distorsion 'Arc' s'efforce grandement de préserver autant que possible l'échelle de l'image d'origine. Pour cela, la ligne médiane horizontale de l'image est fixée au « rayon idéal » correspondant à la largeur et à l'"_arc_angle_" donné de l'image source. Cela signifie que si vous appliquez l'arc à l'image sur un "_arc_angle_" plus grand, le rayon de la ligne médiane utilisée diminuera aussi du même facteur. Ainsi, le rayon de la ligne médiane sera plus petit et plus serré. |

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

[IM Output]
Remarquez que l'image tient désormais dans un cercle plus petit, mais que le bord inférieur de l'image forme un cercle encore plus petit ! Si vous définissez un angle encore plus grand sur lequel appliquer l'arc à l'image, le bord inférieur atteindra le centre de la distorsion, et au-delà, ce qui a pour résultat que la partie inférieure de l'image source disparaît dans le néant.

  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 en anneaux formant un cercle complet

Les images plus longues se distordent bien mieux en 'Arc' sur de très grands angles. Par exemple, vous pouvez enrouler de longues images (comme des messages texte) en anneaux. Et juste pour que vous puissiez vraiment voir ce qui se passe ici, j'ai défini une couleur d'arrière-plan de pixel virtuel différente, afin que vous puissiez voir la limite de l'image d'origine.

  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]

Et hop, nous avons « arqué » l'image de l'étiquette en un cercle complet. Si vous regardez de près la jointure de l'image en cercle complet, vous verrez peut-être une petite ligne de pixels, là où la jointure n'est pas tout à fait complète. Cela est dû à l'effet de l'arrière-plan de pixel virtuel 'SkyBlue' environnant, car nous joignons en réalité deux bords d'une image. Lors de la génération d'un cercle complet, vous devez utiliser une méthode de pixel virtuel qui « joindra » correctement ces deux bords. Cela se fait généralement en utilisant l'une des méthodes de pixel virtuel en mosaïque, telle que Tile. |

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

[IM Output]
Malheureusement, comme vous pouvez le voir, cela ne se contente pas de joindre correctement l'image, mais génère aussi des lignes dupliquées de l'image entrant et sortant de l'anneau principal. Pas bon. À partir d'IM v6.4.2-6, une nouvelle méthode de pixel virtuel, HorizontalTile, résout ce problème. Cette méthode répète l'image en mosaïque uniquement latéralement, de sorte qu'elle crée une bonne jointure pour notre image en cercle, mais remplit les zones au-dessus et en dessous des tuiles avec la couleur d'arrière-plan courante, produisant un cercle de texte parfait. |

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

[IM Output]
Si, avant d'« arquer » une image, vous faites pivoter l'image d'entrée à l'envers, vous pouvez placer le « haut » d'origine de l'image sur le bord intérieur du cercle. Bien sûr, vous voudrez peut-être « faire pivoter » le résultat à nouveau à l'endroit ensuite, mais cette capacité est déjà intégrée à la méthode de distorsion '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]
Le troisième argument "_top_radius_" remplacera le rayon « idéal » de la ligne médiane qui est calculé, de sorte que le haut de l'image devienne un cercle du rayon donné. Cela crée un anneau de 100 pixels de large, bien que l'image l'accueillant fasse 102 pixels de large pour tenir compte des effets d'anticrénelage. |

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

[IM Output]
L'image conserve toujours le même rapport d'aspect, de sorte que le résultat ci-dessus est essentiellement identique au précédent, simplement mis à l'échelle pour s'ajuster au cercle du rayon demandé. Rappelez-vous que le rayon peut être en virgule flottante, mais que le centre d'un arc sera toujours aligné sur un « coin » de pixel, si bien que l'image résultante aura toujours une largeur d'un nombre pair de pixels. Si vous fournissez le quatrième argument « _bottom_radius_ », vous pouvez contrôler entièrement la largeur de l'anneau, ou sa « hauteur radiale ». |

  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]
Cela déforme la mise à l'échelle radiale de l'image et sépare effectivement la mise à l'échelle radiale de la « largeur d'arc », ou angle, de l'image résultante. Autrement dit, le rapport d'aspect de l'image d'origine n'est plus préservé. Vous pouvez même la forcer à remplir complètement l'intérieur du cercle, en enroulant le bord inférieur de l'image d'entrée au centre, ou « pôle », de la déformation. |

  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]

Exemples de déformation Arc

Vous pouvez générer des effets intéressants à l'aide d'une déformation Arc, par exemple en arquant un motif en damier assez allongé dans l'anneau (en utilisant le réglage de pixel virtuel « [HorizontalTile](misc.html#horizontal_tile) », on obtient… |

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

[IM Output]
En utilisant le réglage de pixel virtuel par défaut « [Edge](misc.html#edge) », vous pouvez produire un effet plus intéressant. |

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

[IM Output]
Bien sûr, un réglage « [Tile](misc.html#edge) » a lui aussi généré des effets « radiaux » intéressants, vous permettant de produire un motif en damier circulaire. |

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

[IM Output]
Le résultat ci-dessus peut être affiné davantage en contrôlant les rayons supérieur et inférieur de l'image résultante. Voici quelques exemples supplémentaires de déformation « [Arc](#arc) », mais je vous laisse jouer avec eux pour comprendre comment ils fonctionnent. Qu'êtes-vous capable d'imaginer ? |

  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]
Les « rayons » de ce dernier exemple sont un sous-produit du réglage de pixel virtuel pseudo-aléatoire « [Dither](misc.html#dither) », qui aboutit à un motif de pixels étrange de la couleur « soleil » provenant du coin supérieur gauche de l'image d'origine. Les mêmes effets de tramage produisent aussi la ligne circulaire de « tirets » entourant l'image de « l'arbre ». Vous pouvez obtenir une version similaire et plus contrôlée de cet effet en utilisant un réglage « [Edge](misc.html#edge) » avec une image qui a été modifiée pour ajouter des pixels de bord intéressants.

Placement du point central de l'arc

Par défaut, « [Arc](#arc) » ignore complètement tout décalage de canevas virtuel que l'image peut posséder, et ne signale même pas l'emplacement du « centre » autour duquel l'image a été arquée. Cependant, connaître l'emplacement du « point central » peut être très utile. Si, au lieu d'utiliser « -distort », vous utilisez la forme plus spéciale « +distort », l'image se verra attribuer un canevas virtuel, de sorte que le centre soit situé à l'origine du canevas virtuel. Autrement dit, le point « 0,0 » de l'image est défini comme le « centre » de l'arc. Cela est particulièrement utile pour positionner une image arquée avec un angle plus petit que le cercle complet, où le « centre » de l'arc n'est pas le centre de l'image. Par exemple… |

  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]
Ici, je crée une étiquette de texte que je déforme en « [Arc](#arc) » en un cercle incomplet à l'aide de la forme plus « +distort » de l'opérateur. Le « centre » de l'arc a été soigneusement préservé par IM grâce au décalage de canevas virtuel de l'image. Cela signifie qu'en effectuant simplement un ajustement relatif du décalage à l'aide de « -repage » avec un indicateur « ! », nous pouvons positionner le cercle de texte résultant où bon nous semble ! Par exemple à la pointe du chapeau de magicien, située aux coordonnées de pixel 75,21 dans l'exemple ci-dessus. Malheureusement, comme des décalages virtuels sont utilisés pour positionner l'image, le positionnement exact est limité à des tailles de pixels entières. Vous ne pouvez pas positionner une déformation Arc à un emplacement défini au sous-pixel sans effectuer une seconde déformation. En revanche, vous pouvez le faire pour une déformation polaire (voir ci-après).

Déformation polaire (déformations en cercle complet)

La déformation « Polar » (ajoutée dans IM v6.4.2-6) est une version plus bas niveau de la déformation « [Arc](#arc) » ci-dessus. Mais elle n'effectue pas automatiquement le « bestfit » et n'essaie pas non plus de préserver les rapports d'aspect des images. Les 6 arguments optionnels en virgule flottante sont… Radius_Max Radius_Min Center_X,Center_Y Start_Angle,End_Angle

Tous les arguments sont optionnels à leurs positions séparées par des espaces. Par défaut, « CenterX,Y » prend pour valeur le milieu exact de la zone de l'image d'entrée. Ensuite, une image polaire en cercle complet est générée de telle sorte que tout le bord supérieur devienne le centre, tandis que le bord inférieur est enroulé complètement autour de l'extérieur du cercle. Les bords gauche et droit se rejoignent au-dessus du point central, aux angles « -180 » à « +180 » de l'image. Comme « Radius_Max » doit être fourni, il doit avoir une valeur positive. Cependant, si vous donnez la valeur « 0 », il sera défini comme la distance entre le centre et le bord le plus proche, de sorte que si les autres valeurs ne sont pas fournies (valeurs par défaut), toute l'image d'entrée est mappée dans un cercle au milieu de l'image. Par exemple, transformons une carte du monde en une vue polaire, en utilisant toutes les valeurs par défaut. Bien entendu, vous devez spécifier un réglage de pixel virtuel « [HorizontalTile](misc.html#horizontal_tile) » lors de la production d'un mappage polaire en cercle complet…

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

[IM Output] [IM Output]

Bien entendu, cela déforme gravement l'hémisphère sud, enroulant l'Antarctique complètement autour de la circonférence de ce « disque-monde ». En faisant pivoter l'image source et en la rognant de manière à ne montrer que la calotte polaire, nous pouvons générer une jolie carte du continent antarctique. J'ai également spécifié un rayon de sortie plus grand, pour le rendre plus visible, et demandé à IM d'« ajuster » l'image de sortie à cette taille en utilisant la forme « plus » de l'opérateur de déformation. |

  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]
Notez que les vues ci-dessus ne sont pas des vues strictement correctes de la Terre, car la carte cartésienne est une représentation d'une sphère, et non une image en coordonnées polaires. Si vous utilisez une valeur spéciale de « Radius_Max » exactement égale à « -1 », le rayon de l'image déformée est fixé à la distance du centre au coin le plus éloigné (diagonale). Cela vise à fournir un « inverse » idéal pour une déformation « [DePolar](#depolar) » d'image complète, que nous examinerons ensuite. (Voir Astuces (Dé)Polar ci-dessous pour des exemples d'utilisation.) | Rappelez-vous que, contrairement à une déformation « [Arc](#arc) », « [Polar](#polar) » (également connue sous le nom de déformation « cartésienne vers polaire ») ne fait aucune tentative de préserver le rapport d'aspect « idéal » de l'image source. La prudence est de mise.
---|---
Les arguments « CenterX,Y » sont surtout utiles pour positionner le centre de l'image résultante à un décalage sous-pixel. C'est-à-dire, selon que le centre se trouve à la limite d'un pixel (nombre entier) ou au centre d'un pixel (avec des décalages de 0.5). Bien entendu, ils déterminent aussi l'emplacement de la « couche » du canevas virtuel. Par défaut cependant, il reçoit la valeur du milieu de l'image (pour « -distort », qui utilise l'image d'entrée comme fenêtre d'affichage) ou 0,0 (pour l'image de couche « +distort »). Les arguments suivants « Start_Angle,End_Angle sont encore moins couramment utilisés ; ils limitent les angles couverts par l'image d'entrée, avec une valeur par défaut de -180 à 180 degrés (0 étant droit vers le bas). Comme pour la déformation « [Arc](#arc) », vous pourriez l'utiliser pour faire pivoter l'image polaire résultante. Mais on peut aussi s'en servir pour générer des « arcs ». Par exemple…

  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]

Notez qu'actuellement IM ne réduit pas la taille de l'image de couche résultante, qui est alignée de sorte que l'origine de l'image virtuelle se trouve aux coordonnées 0,0, comme demandé. Hormis le style des arguments, c'est la plus grande différence entre les déformations « [Arc](#arc) » et « [Polar](#polar) ». Notez également que le bord gauche (angle -60) se trouve à gauche. C'est mathématiquement correct si l'on considère que l'axe « Y » est orienté vers le bas (comme pour toutes les rotations d'image). Bien entendu, comme pour Arc, vous pouvez utiliser les effets de pavage de pixel virtuel pour générer des motifs répétés. Par exemple, ceci est exactement identique au dernier exemple, juste avec un réglage « [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]

Déformation DePolar (polaire vers cartésienne)

Il s'agit essentiellement de l'inverse d'une déformation « [Polar](#polar) », et elle possède exactement le même jeu d'arguments optionnels. Les 6 arguments optionnels en virgule flottante sont…

Radius_Max Radius_Min Center_X,Center_Y Start_Angle,End_Angle

Ici encore, si « Radius_Max » est fixé à « 0 », la distance de « CenterX,Y » au bord le plus proche est utilisée, ce qui signifie que tout ce qui se trouve dans le plus grand cercle complet sera mappé pour s'ajuster à une image de la même taille que l'image d'entrée. Par exemple, inversons le « disque-monde » précédent pour le ramener à une carte cartésienne.

  magick polar_arctic.jpg  -distort DePolar 0  world_restored.jpg

[IM Output] [IM Output]

Comme la taille de l'image d'entrée a été préservée tout au long des deux déformations, le résultat ci-dessus est fondamentalement identique à la carte d'origine. Bien entendu, comme l'image a été comprimée à la fois au « pôle » supérieur et en rayon, la sortie est bien plus floue que ce à quoi on pourrait s'attendre. En réalité, cela est aggravé par le fait que l'algorithme derééchantillonnage par zone (EWA) ne peut pas échantillonner les pixels selon un arc de cercle. C'est pourquoi le rééchantillonnage par zone est désactivé pour les déformations « [DePolar](#depolar) ». Il est recommandé d'utiliser à la place une forme de technique de suréchantillonnage, comme illustré dans la section suivante.
Si vous laissez IM utiliser le « bestfit » (en utilisant la forme « +distort » de l'opérateur), il redimensionnera alors l'image de sortie de manière à conserver « Radius_Max » à une échelle unitaire, et fixera la largeur à la distance de circonférence du rayon situé à mi-chemin entre « Radius_Max » et « Radius_Min ». Cela tente essentiellement de préserver au mieux le rapport d'aspect de l'image polaire, bien que cela puisse produire une image plus longue et plus fine que prévu. Par exemple.
  magick polar_arctic.jpg  +distort DePolar 0  world_restored_2.jpg

[IM Output] [IM Output]

Astuces du cycle (Dé)Polar (flous radiaux/angulaires)

Comme nous l'avons vu ci-dessus, l'utilisation d'un « Radius_Max » de « 0 » garantira que toute l'image sera mappée dans un cercle lors de l'utilisation d'une déformation « [Polar](#polar) » (cartésienne vers polaire), et le même réglage remappera ce cercle en une image rectangulaire à l'aide de « [DePolar](#depolar) » (polaire vers cartésienne). Cependant, cela ne fonctionnera pas très bien si vous souhaitez « [DePolar](#depolar) » une image rectangulaire, puis inverser à nouveau la déformation avec « [Polar](#polar) ». Par exemple, prenons une image de fleur, dépolarisons-la, puis restaurons-la à l'aide de la valeur spéciale de « Radius_Max » de « 0 » (rayon = bord le plus proche).

  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]

Ici, l'image n'est pas correctement restaurée, car elle a été rognée par la première déformation « [DePolar](#depolar) ». Même ainsi, ceci constitue en soi une technique utile, qui peut servir à générer des masques circulaires parfaits pour une image existante, dimensionnés d'une manière totalement indépendante de l'image d'entrée fournie. Pour effectuer correctement cette technique de cycle « [DePolar](#depolar) »-« [Polar](#polar) », nous devons utiliser un rayon égal à la distance du centre au coin le plus éloigné. La valeur spéciale de « Radius_Max » de « -1 » demande à IM de calculer et d'utiliser le coin le plus éloigné du « point central » comme rayon.

  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]

L'image restaurée est légèrement floue, ce qui est dû à la compression du rayon nécessaire pour préserver l'image entière lors de l'opération « [DePolar](#depolar) ». Cela peut toutefois être corrigé en utilisant une technique de suréchantillonnage appropriée (voir la série d'exemples suivante). Mais pourquoi voudrait-on transformer une image sous cette forme puis la ramener à son état initial ? Eh bien, en appliquant d'autres déformations à la version intermédiaire « DePolar » de l'image, vous pouvez générer très facilement des effets radiaux ou angulaires très sophistiqués. Par exemple, en faisant rouler l'image intermédiaire, vous ferez pivoter l'image de sortie, bien que vous puissiez obtenir un certain rognage des coins… |

  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]
Notez que le sens de la rotation est inversé par rapport à celui de l'opérateur Rotate ou de la déformation SRT.

Problèmes du cycle Depolar-Polar

Dans la rotation d'image ci-dessus, vous avez peut-être remarqué des déformations en « escalier » le long du bord de l'image pivotée. C'est un problème bien connu, causé par la compression de la grande circonférence circulaire de l'image dans la « largeur » plus petite de l'image d'entrée. Par exemple, ici je prends l'image de test en damier et je la fais simplement passer par un cycle Depolar-Polar normal sans effectuer aucune modification.

  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]

Vous pouvez clairement voir les effets de crénelage causés par la compression de l'image aux pointes de l'image intermédiaire. Cela est également exacerbé par le fait que le rééchantillonnage par zone normal n'est pas utilisé lors de cette conversion « [Depolar](#depolar) » initiale de l'image d'entrée. La meilleure façon de résoudre ce problème est d'utiliser la mise à l'échelle de la sortie de Distort pour à la fois agrandir l'image intermédiaire, puis réduire l'image finale. Cela fournira un résultat suréchantillonné qui éliminera les artefacts de compression observés ci-dessus. Par exemple, voici le meilleur cycle depolar-polar « sans effet », le tout en une seule commande… |

  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]
Comme vous pouvez le voir, les horribles effets de crénelage ont presque totalement disparu. Attention toutefois : une image très haute et fine pourrait faire réapparaître le problème. Le mieux est de limiter cela à des images « paysage » ou larges, avec le suréchantillonnage montré ci-dessus. Il ne vous reste plus qu'à remplacer l'opérateur « -noop » par la commande appropriée pour générer l'effet radial et rotationnel recherché.

Exemple d'effets Depolar-Polar

Montrons donc à nouveau une meilleure rotation polaire de l'image, cette fois en utilisant le suréchantillonnage. Notez cependant que, comme l'image intermédiaire est 4 fois plus grande, la quantité de décalage circulaire d'image doit elle aussi être 4 fois plus grande. |

  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]
Comme vous pouvez le voir, l'effet d'« escalier » le long du bord a été supprimé, avec un résultat d'image de bien meilleure qualité.
Vous pouvez aussi appliquer un simple flou linéaire à l'image intermédiaire (obtenu en la compressant puis en l'agrandissant de nouveau). |

  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]
Le résultat est très proche d'un « flou rotationnel » de l'image. Cela ressemble à l'opérateur de flou radial au nom mal choisi, sans toutefois lui être tout à fait identique. En réalité, les résultats sont de meilleure qualité que cette méthode de flou spécialisée. Notez que l'utilisation d'une couleur « black » dans les diverses formes de réglages de pixel virtuel appliquées entraînera un léger assombrissement des bords, mais ce n'est pas trop gênant dans le cas ci-dessus. Une méthode pour éliminer les effets de bords « noirs » serait d'utiliser à la place la couleur « transparency », puis de désactiver complètement le canal alpha une fois terminé, afin de ne laisser que la couleur réelle que IM a calculée. Une autre consiste à utiliser deux méthodes de pixel virtuel « edge » (« [Edge](misc.html#edge) » et « [HorizontalTileEdge](misc.html#horizontal_edge) »), qui étendent les bords de l'image dans l'espace de canevas virtuel non défini. |

  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]
Ce qui montre un bien meilleur résultat près des bords.
En floutant verticalement la version polaire de l'image, cette fois à l'aide de l'opérateur Motion Blur plutôt que de la compression par redimensionnement, vous pouvez générer des traînées radiales qui s'éloignent du centre de l'image... |

  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]
Pour que le résultat ne floute que les hautes lumières (les pétales) de l'image, vous pouvez le composer avec l'image d'origine à l'aide de Lighten, de sorte que seules les couleurs plus claires floutées restent visibles, sans que les couleurs sombres ne débordent en floutant vers les zones plus claires et ne détruisent les points jaunes au milieu de la fleur. |

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

[IM Output]
Voir aussi Étoiles et comètes pour un autre exemple de ce procédé, mais générant directement l'image intermédiaire « DePolar » avant d'appliquer une déformation « [Polar](#polar) ». Un remerciement particulier va à Fred Weinhaus pour les usages spéciaux du cycle DePolar-Polar, et pour avoir insisté afin que je m'assure que ces déformations soient entièrement réversibles pour les images rectangulaires. Il met cette technique à profit dans nombre de ses scripts ImageMagick, notamment « [bump](http://www.fmwconcepts.com/imagemagick/bump/index.php) », « [ripples](http://www.fmwconcepts.com/imagemagick/ripples/index.php) » et « [striations](http://www.fmwconcepts.com/imagemagick/striations/index.php) ».

Déformation en barillet (correction des distorsions d'objectif)

La déformation en barillet (ajoutée dans IM v6.4.2-4) est spécialement conçue pour corriger les distorsions sphériques provoquées par les objectifs des appareils photo dans les photos. C'est-à-dire des distorsions telles que les effets de barillet et de coussinet, qui sont effectivement l'inverse l'un de l'autre. Pour l'application concrète de cet opérateur à la correction des distorsions d'objectif, voir la section Correction d'objectif. La déformation est implémentée sur la base d'un ensemble de 4 valeurs de coefficients, connus sous les noms de A, B, C et D, tels que définis par le professeur Helmut Dersch, sur un site web qui a depuis disparu. Vous pouvez consulter une archive du site par la Wayback Machine à l'adresse Correcting Barrel Distortion. Les valeurs forment essentiellement une équation de distorsion telle que…

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

Où « _r_ » est le rayon de destination et « _R src_ » le pixel source d'où obtenir la couleur du pixel. Les rayons sont normalisés de sorte que radius = « 1.0 » pour la moitié de la largeur ou de la hauteur minimale de l'image d'entrée. Cela peut sembler inversé, mais c'est parce que la technique de mappage inverse des pixels est utilisée pour garantir une couverture complète de l'image résultante. Les quatre coefficients (A, B, C et D) sont fixes pour toute combinaison spécifique d'appareil photo, d'objectif et de zoom. Ces trois éléments sont généralement stockés avec l'image dans un profil EXIF. C'est important, car cela signifie qu'une fois que vous disposez de ces valeurs pour votre appareil photo, vous pouvez les utiliser pour supprimer la distorsion sphérique d'objectif présente dans toutes les photos prises avec cette combinaison d'appareil et d'objectif. Les arguments nécessaires à la méthode de déformation « **Barrel** ». En général, vous ne fournissez que 3 ou 4 valeurs…

_A B C_ [ _D_ [ _X_ , _Y_ ] ]

Les arguments optionnels X ,Y fournissent un « centre » optionnel pour la distorsion radiale ; à défaut, celui-ci prend par défaut le centre exact de l'image fournie (indépendamment de son décalage virtuel). Les coefficients sont conçus de telle sorte que si les quatre valeurs A à D totalisent « 1.0 », la largeur/hauteur minimale de l'image ne changera pas. Pour cette raison, si D (qui contrôle la mise à l'échelle globale de l'image) n'est pas fourni, il sera défini de sorte que les quatre valeurs totalisent bien « 1.0 ». L'utilisation des paramètres « 0.0 0.0 0.0 » (équivalent à _A_ =_B_ =_C_ =0.0 et _D_ =1.0 ») ne produira aucun changement sur l'image d'entrée, et constitue l'argument « sans effet » de cette déformation. Voici un exemple tiré du site web d'origine, utilisant les coefficients fournis pour l'appareil photo qui a servi à prendre la photo.

  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]

Remarquez comment la distorsion de l'image a été corrigée, rendant droits les piliers du bâtiment. Cependant, comme les 4 coefficients totalisaient une valeur supérieure à 1.0, l'image a été réduite d'une petite quantité, produisant les petites zones noires au milieu des bords supérieur et inférieur (selon le réglage de pixel virtuel fourni). Voici l'effet de l'ajout de 0.2 à chacun des coefficients d'entrée ; là encore, les valeurs totalisent plus de 1.0, si bien que l'image déformée résultante sera plus petite.

  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]

Soustraire 0.2 produit l'effet inverse, bien que j'aie compensé l'effet à l'aide d'une valeur « D » plus grande (pour réduire l'image) afin que vous puissiez mieux voir les résultats.

  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]

Remarquez comment la valeur de A produit un effet plus important que B , et B un effet plus important que C , tandis que D assure une mise à l'échelle globale du résultat. Cela permet d'utiliser chaque coefficient pour ajuster l'image afin de corriger une distorsion sur le bord extérieur et une autre distorsion vers le milieu, l'une pouvant être en coussinet et l'autre en barillet. Très polyvalent. Les coefficients ci-dessus (A , B , C et D) sont conçus pour fonctionner avec un rayon « normalisé » égal à la moitié de la plus petite largeur ou hauteur de l'image (comme le réglage de rayon « 0 » de la distorsion polaire. Autrement dit, ils sont indépendants de la taille de l'image. Vous pouvez donc utiliser le même jeu de valeurs pour n'importe quelle image produite par un appareil photo donné, quelle que soit sa taille de qualité (réglage de l'appareil), ou si vous avez redimensionné l'image plus petite. Il est possible d'ajuster les valeurs des coefficients pour utiliser d'autres rayons « normalisés » en appliquant les multiplicateurs/diviseurs appropriés à chaque coefficient. Par exemple en utilisant la moitié de la largeur/hauteur maximale, ou le rayon diagonal. | _Helmut Dersch note également que vous devriez envisager d'utiliser un espace colorimétrique LAB pour la correction de distorsion des photos, car il produit une meilleure interpolation des couleurs. Cela peut en fait être vrai pour toutes les distorsions (y compris le Resize.

Les tests montrent que l'espace LAB est tout aussi non linéaire que sRGB, mais il évite la possibilité de distorsions de couleur lorsque des valeurs extrêmes sont écrêtées. Voir Perception humaine des couleurs, et les exemples pratiques dans Redimensionnement avec correction d'espace colorimétrique._
---|---

Vous pouvez aussi déclarer un jeu de coefficients différent pour les axes x et y, ce qui permet de générer des distorsions inhabituelles.

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

L'utilisation d'arguments X et Y séparés a été prototypée dans le script pinbarrel de Fred Weinhaus, bien que ses arguments soient dans l'ordre inverse, avec D en premier et A en dernier. En utilisant une valeur C positive, avec une valeur D appropriée pour le seul jeu de coefficients « y », vous pouvez déformer les images de sorte qu'elles se bombent verticalement au milieu. |

  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 même, en utilisant une valeur C négative, vous pouvez « pincer » une image au milieu. |

  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, en ajoutant l'effet inverse pour les coefficients X, vous pouvez donner l'impression que vous pressez l'image entre vos doigts, la faisant se bomber sur les côtés. |

  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]

Distorsion BarrelInverse (distorsion en barillet alternative)

La méthode de distorsion « BarrelInverse » est très similaire à la méthode de distorsion en barillet précédente, et prend en fait le même jeu d'arguments. Cependant la formule appliquée est légèrement différente, la partie principale de l'équation divisant le rayon. C'est-à-dire que l'équation a été inversée.

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

| Cette équation ne produit PAS l'« inverse » de la distorsion « Barrel ». Vous ne pouvez PAS l'utiliser pour « annuler » la distorsion précédente.
---|---
Il en résulte que vous utiliseriez la forme « négative » de A , B , C , avec un ajustement équivalent de D pour obtenir un résultat similaire mais légèrement différent. Certaines sources telles que l'article de recherche Method for Correcting Lens Distortion (PDF) suggèrent qu'un meilleur résultat peut être obtenu avec une distorsion de correction d'objectif de cette forme. Par exemple, voici l'équivalent du dernier exemple « Pinch » en utilisant cette forme de distorsion. |

  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]


Distorsions projectives

Ce sont des distorsions utilisées pour projeter ou mapper des images qui existent sur une surface, sur une autre surface. Les lignes de projection peuvent être parallèles, ou rayonner depuis un emplacement spécifique. Bien que techniquement les distorsions affines et perspectives soient également « projectives » en ce sens qu'elles « projettent » des images d'une surface plane sur une autre surface plane (en utilisant respectivement des projections parallèles et radiales), elles sont si courantes qu'elles sont examinées plus en détail dans leurs propres sections d'exemples ci-dessus. Voici les « distorsions projectives » plus inhabituelles qui ont été implémentées, généralement avec l'aide du forum de discussion IM.

Cylinder 2 Plane

La distorsion « Cylinder2Plane » est une distorsion projective radiale depuis un point situé au centre d'un cylindre vers un plan plat tangent à ce cylindre.

[diagram]

Cet agencement est typique d'un appareil sténopé spécial connu sous le nom de caméra P.90. où une photo d'un arc de 90 degrés est capturée sur un film qui forme un cylindre dans l'appareil. Voici un exemple de photo prise par une telle caméra…

[photo]

Le problème est que l'image résultante est déformée, de sorte que les lignes droites deviennent des arcs courbes, en raison de l'agencement physique du film. Il s'agit essentiellement d'une surface courbe s'enroulant autour d'une source de projection « ponctuelle » (un sténopé). Notez qu'un appareil sténopé normal n'a pas ce problème puisque vous projetez sur une surface plane depuis une source ponctuelle. La distorsion « Cylinder2Plane » corrige cela en projetant l'image depuis son agencement cylindrique sur un plan plat. Elle prend les paramètres…

_fov_angle center_x,y fov_output dest_center_x,y_

Seul le premier paramètre, l'angle du champ de vision de la caméra, est requis. Pour une caméra P.90, elle utilisait une distance focale (radiale) de 90 mm et un film standard de 57 mm de large, ce qui produit à son tour un « champ de vision » de 90 / 57 * 180/pi soit 90,467 degrés. Ici par exemple, je projette une photo P90 sur un plan pour rendre l'image plus « normale » et rendre à nouveau droites les lignes droites.

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

[IM Output]

Notez que la largeur et la hauteur de l'image ont toutes deux changé, car nous utilisons la version « plus » de la distorsion, de manière à montrer tous les pixels déformés de l'image d'origine. Elle est plus large à cause de la projection, tandis que la hauteur de l'image réelle le long de la ligne centrale verticale n'a pas changé. La photo et l'algorithme proviennent d'une discussion IM Correcting for a curved film plane. La discussion a aussi débordé sur une autre discussion, Algorithmic vignetting correction for pinhole cameras.
Le paramètre spécial « fov_output » , s'il est donné, mettra à l'échelle l'image de sortie résultante de sorte que la largeur de l'image de sortie (typiquement une taille de fenêtre d'affichage) corresponde exactement à cet angle. Si aucune fenêtre d'affichage n'est donnée, une meilleure correspondance est activée, afin d'approximer au mieux une mise à l'échelle 1:1 de l'image, tout en alignant les bords de l'image sur des entiers. Le paramètre du point central de la distorsion (point de tangence et d'horizon de l'entrée). Le dernier paramètre « center » contrôle le positionnement précis en virgule flottante des résultats dans la « couche » de l'image de la fenêtre d'affichage (c'est-à-dire des translations sous-pixel). Avec le paramètre « center_x,y » , cela permet d'extraire des parties d'une image plus grande. Par exemple, extraire une petite vue à 90 degrés d'une image panoramique à 360 degrés plus grande. AVENIR : extraire de plus petites images de « visualisation » plates d'un panorama à 360, ainsi qu'une animation qui panoramique lentement autour de ces 360 degrés.

Plane 2 Cylinder

La distorsion « Plane2Cylinder » est l'inverse de la projection ci-dessus, et prend les paramètres…

_fov_angle center_x,y_

Par exemple, ceci annule l'exemple précédent de la caméra P.90.

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

[IM Output]

Les résultats contiennent toujours les pixels supplémentaires ajoutés précédemment, et en ajoutent encore davantage. Ceux-ci devraient être rognés du résultat ci-dessus. Ici, j'utilise cette distorsion pour générer une animation d'une « bande de film » complète avec les trous de perforation du bord du film.

  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]

Explication :

  • D'abord une image de trou est dessinée, qui est dupliquée et ajoutée pour former une séquence de 6 trous. Puis dupliquée à nouveau.
  • Une image de rose intégrée est alors ajoutée et prise en sandwich entre les deux copies de ces trous de perforation, le tout étant ajouté ensemble (avec un remplissage noir) pour créer une seule image de la bande de film finale.
  • Ceci est dupliqué pour créer une bande de film de 4 images, qui définira la longueur de l'image finale.
  • Une animation de 20 images est créée en utilisant des distorsions SRT de « translation ». Voir Animations par distorsion.
  • Ensuite chacune de ces 20 images est déformée sur un cylindre selon un arc de 115 degrés, en utilisant un réglage de pixel virtuel pour générer une tuile horizontale infinie de la bande de film
  • L'angle dans ce cas ne concerne que la largeur de l'image d'entrée ; la largeur de l'image finale dépasse 180 degrés, car je n'ai pas utilisé de version « plus » de la distorsion. Ainsi, bien que la largeur déformée rétrécisse en largeur, l'image de sortie ne rétrécit pas.
  • Une bordure finale est ajoutée, et les réglages d'animation sont appliqués.

Distorsions multipoints et à main levée

Distorsion de Shepard (distorsion façon caramel mou)

La méthode de Shepard (ajoutée à IM v6.4.2-4) utilise le déplacement des points de contrôle donnés pour déformer l'image en termes d'effets « locaux ». On peut se la représenter comme équivalente à un épais bloc de « caramel mou » représentant l'image source, dans lequel on planterait des épingles que l'on déplacerait ensuite. Plus techniquement, elle déplace les points selon une interpolation par distance inverse au carré. Si un seul point de contrôle est utilisé, l'image entière est naturellement déplacée (translatée), exactement comme on l'obtiendrait pour une distorsion « [Affine](#affine) » à un point. Peu intéressant. Essayons donc de déplacer deux points de contrôle. Par exemple, torturons le « koala » en tirant sur ses oreilles (en « 30,11 » et « 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]

Comme vous pouvez le voir, les parties de l'image situées entre les deux points de contrôle ont été étirées à cause du déplacement des points de contrôle. Cependant, toutes les autres parties de l'image sont restées quasiment intactes, y compris l'image proche du point de contrôle lui-même, le bas de l'image, et ainsi de suite. La zone située au milieu, entre les points de contrôle, a été tirée et étirée pour garantir que les points de contrôle soient positionnés là où vous l'aviez demandé. Ce qui est peut-être moins perceptible, c'est que les parties situées de l'autre côté des points de contrôle sont également comprimées, de sorte qu'à mesure que l'on s'éloigne, les points de contrôle ont moins d'influence sur le résultat. Autrement dit, cette distorsion génère une distorsion « localisée ». Élargissons notre vue (en utilisant une fenêtre d'affichage de distorsion) pour mieux le voir… |

  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]
Comme vous pouvez le voir, la forme de l'image a également été déformée pour s'adapter à la « tête » étirée du koala. Pour éviter cet effet, il est plus courant d'« épingler » aussi les coins et éventuellement certains bords de l'image, afin qu'ils ne bougent pas. |

  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]
Même le simple déplacement d'un seul point, tout en épinglant d'autres points (dans ce cas juste les coins), peut être utile. Par exemple, déplaçons simplement le nez du koala (en « 28,24 ») vers le milieu de l'image. |

  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]
Cet exemple particulier est spécial car il s'agit de la distorsion utilisée par Fred Weinhaus pour son script de « morphing animé » à point unique « [shapemorph](http://www.fmwconcepts.com/imagemagick/shapemorph/) ». Cependant son script d'origine utilisait un lent opérateur FX artisanal, car la distorsion de Shepard n'avait pas encore été ajoutée à IM. Ce script est en fait à l'origine de l'idée de la distorsion de Shepard.

Déplacer des zones d'une image

Vous pouvez même déplacer des sections entières de l'image en déplaçant ensemble un ensemble de points autour de cette section. Par exemple, déplaçons la tête du koala de côté en utilisant des points autour de la tête (ligne rouge), mais en épinglant aussi les parties de l'image que nous ne voulons pas déplacer (ligne verte).

  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]

Notez que si la tête a bien été déplacée, le bord de la tête se retrouve fortement déformé. La raison en est que la distorsion ne déplace pas des zones, mais des points. Si ces points marquant le bord sont trop éloignés les uns des autres, l'image va en quelque sorte dégouliner, fuir ou se plier entre ces points, comme du caramel mou ou de la gelée. (À NOTER : le terme exact est l'étirement d'une « feuille de caoutchouc » ou d'un « ballon »). De plus, si deux points de contrôle sont proches l'un de l'autre mais se déplacent dans des directions ou selon des amplitudes différentes, l'image pourra localement tourbillonner et se plier autour d'eux. Les points de contrôle finissent tout de même aux bons emplacements, mais tout ce qui les entoure est gravement déformé pour atteindre cet objectif. Et c'est ce qui se passe le long du bord de la tête. Alors, à quelle distance les points marquant le bord doivent-ils être ? Fondamentalement, au moins à la moitié de la distance de tout autre point qui se déplace différemment. Donc, soit ajoutez davantage de points de bord, soit mettez un peu plus de distance entre les points fixes et les points en mouvement. En faisant cela, vous définirez mieux l'espace dans lequel l'image peut être étirée et comprimée. Notez aussi que l'image entière s'est globalement déplacée vers la gauche, en même temps que la tête. Seuls les points de contrôle qui étaient soit fixés, soit déplacés vers des destinations précises, sont garantis d'être placés correctement. Toutes les parties de l'image plus éloignées des points de contrôle se déplaceront également selon une moyenne approximative de tous les déplacements des points de contrôle. Il est donc préférable d'avoir beaucoup plus de points « fixes », répartis dans toute l'image, ou même quelques points déplacés négativement, à une certaine distance à l'extérieur de l'image, afin de compenser le déplacement moyen général. Vous pouvez aussi dupliquer ou doubler les points de contrôle (les lister deux fois) pour donner à certains points davantage d'influence ou de « puissance » sur la distorsion dans cette zone. Voici une autre version du « déplacement de la tête de côté », mais cette fois j'ai donné un peu plus de séparation entre les points en mouvement (rouge) et fixes (vert). J'ai aussi ajouté beaucoup plus de points fixes pour réduire le déplacement moyen général de l'image déformée.

  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]

La dernière chose à faire dans l'exemple ci-dessus est simplement de définir un meilleur réglage « [-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) » pour choisir la couleur que devraient prendre les zones noires non définies ci-dessus.

Shepard et les rotations d'image

Un aspect de cette distorsion est qu'elle n'aime aucune forme de rotation ! Par exemple, voici une répétition des distorsions Perspective et BilinearForward, aux côtés de la distorsion 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]
Bilinéaire | [IM Output]
Shepards
---|---|---|---|---

Remarquez comment la distorsion de Shepard a produit une image très incurvée par rapport aux deux autres méthodes de distorsion. Cela vient du fait qu'elle tente de préserver l'image exactement dans la zone proche des points de contrôle donnés. Et cela inclut la rotation de l'image. En conséquence de cette « préservation », la grille est incurvée de manière à rester « orthogonale » au point de contrôle réel. C'est un peu comme si les « épingles » aux points de contrôle n'étaient pas en réalité des épingles rondes, mais des « croix », forçant la « gelée » ou la « feuille de caoutchouc » qui tient l'image à préserver aussi la rotation de l'image. C'est aussi la source de nombreux effets de « tourbillon » que cette distorsion peut produire. Par exemple, si l'on prend deux points de l'image et qu'on les pousse l'un au-delà de l'autre, l'image tourbillonne au lieu de tourner. Par exemple, essayons de pousser les oreilles du koala l'une vers l'autre plutôt que de les écarter.

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

[IM Output] [IM Output]

Le facteur de puissance de Shepard

Normalement, les poids de distance d'une IWD (Inverse Weighted Distance, distance inverse pondérée) de Shepard suivent une loi en carré inverse (1/r2), cependant depuis IM v6.8.0-10 vous pouvez maintenant utiliser le define expert « shepards:power » pour contrôler le « niveau de puissance » des poids globaux. S'il n'est pas défini, il a une valeur de 2,0, mais en le définissant plus petit, vous pouvez générer des distorsions plus localisées autour des points de contrôle déplacés, à partir du déplacement moyen global de l'image déformée. Utiliser une valeur plus grande génère une zone d'effet plus large autour des points de contrôle. Par exemple, voici une répétition de l'exemple de « tirage des oreilles du koala », avec différents niveaux de puissance appliqués aux poids de distorsion.

  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
& action | | [IM Output]
power 0.5 | [IM Output]
power 1.0 | [IM Output]
power 2.0
(par défaut) | [IM Output]
power 3.0 | [IM Output]
power 8.0
---|---|---|---|---|---|---

Tous les résultats d'image ci-dessus utilisent exactement le même jeu de déplacements de points de contrôle. La seule différence est la zone d'effet autour de ces points de contrôle. Une petite puissance « localise » les déplacements uniquement à la zone proche du point de contrôle, tandis que des puissances plus grandes entraînent avec elles une plus grande partie de l'image autour du point de contrôle. À de très grandes puissances, cette traction tend à « déchirer » l'image en zones distinctes le long des lignes situées à mi-chemin entre les points de contrôle. Vous pourriez même utiliser des puissances beaucoup plus grandes, qui se contenteront de translater des régions autour du point de contrôle source, vers des zones autour du point de contrôle de destination. Ces zones forment un motif de « régions de Voronoï » et peuvent contenir des copies dupliquées de l'image source. Par exemple, ici je mappe la zone autour du nez du koala (aux coordonnées 28,24), vers 7 zones différentes en motif hexagonal, produisant un effet façon « œil d'insecte » de manière très efficace. |

  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]
Rappelez-vous que la distorsion de Shepard est en fait équivalente à une carte de déplacement (mappant les pixels de destination sur l'image source) générée à l'aide de la même technique que l'opérateur de couleur clairsemée de Shepard, qui est également affecté par ce même define de facteur de puissance.

La distorsion de Shepard, en résumé

La distorsion de Shepard est une méthode très polyvalente et à main levée, qui limite ses distorsions aux zones marquées par les déplacements, ou les non-déplacements, des points donnés. Ses distorsions sont localisées et restreintes en fonction des distances entre les points de contrôle voisins, bien que tous les points aient tout de même un effet global moyenné. Rappelez-vous simplement que cette distorsion est pilotée par des points, et non par des lignes ou des zones, de sorte que les parties situées entre les points peuvent se bomber ou tourbillonner de façon inattendue lorsque des points de contrôle, qui se déplacent différemment, sont positionnés trop près les uns des autres. Elle fait tourbillonner, étire et comprime l'image entre les points de contrôle, mais elle s'efforce de ne pas faire tourner ni mettre à l'échelle l'image près des points de contrôle. Et enfin, elle peut produire une translation moyenne globale de l'image loin de tout point de contrôle. Cependant, si des blocs de points de contrôle peuvent être déplacés en préservant leurs positions relatives générales, elle fournit un moyen d'implémenter une technique de « morphing d'image » générale, pilotée par points, et très simple. Le script « shapemorph2 » de Fred Weinhaus utilise la distorsion de Shepard pour fournir un bon programme de « morphing d'image animé » polyvalent. En interne, cette distorsion est équivalente à l'utilisation du générateur de dégradé Shepards Sparse Color pour créer deux cartes de déplacement relatif qui déforment l'image. C'est ce que fait le script « [shapemorph](http://www.fmwconcepts.com/imagemagick/shapemorph/) » original de Fred Weinhaus, et c'était la source de cette technique de distorsion.
En raison de la complexité des calculs nécessaires à l'utilisation de la distorsion de Shepard, IM ne fournit aucune forme de fenêtre d'affichage de destination « best-fit » via la forme plus « [+distort](#distort_bestfit) » de l'opérateur. Vous pouvez toutefois toujours utiliser l'option fenêtre d'affichage de distorsion pour définir une image de sortie plus grande.
--- ---
Pour les mêmes raisons, le rééchantillonnage de zone est désactivé. Ainsi, les zones de compression extrême (plus d'un facteur 2) présenteront probablement quelques effets d'aliasing. Par exemple, voir les bords du motif hexagonal dans le dernier exemple. Cependant, le suréchantillonnage peut être utilisé pour améliorer la qualité finale des résultats et réduire ces effets d'aliasing.
--- ---