5.24. Transformations polaires

Les coordonnées polaires désignent chaque pixel par un angle mesuré depuis une direction de référence et une distance depuis un centre choisi, à la place des décalages horizontaux et verticaux par rapport à l’origine en haut à gauche. Cette représentation justifie son intérêt par une identité : une rotation autour du centre choisi devient une translation le long de l’axe des angles, ce qui permet à un algorithme invariant en rotation d’explorer un espace de paramètres bien plus simple que les rotations directes. linpolar() et logpolar() effectuent la reprojection.

5.24.1. Les deux méthodes

linpolar() effectue la reprojection cartésienne vers polaire avec un axe de distance linéaire. Chaque colonne de sortie correspond à un angle fixe autour du centre ; chaque ligne de sortie correspond à une distance fixe par rapport au centre.

img.linpolar()

logpolar() effectue la même reprojection avec un axe de distance logarithmique. La gestion des angles est identique ; ce qui diffère, c’est que les distances croissent de façon exponentielle au fil des lignes de sortie plutôt que linéairement. Cette différence est importante en raison de la seconde identité géométrique qu’exposent les coordonnées polaires : la mise à l’échelle de la source autour du centre choisi devient une translation le long de l’axe des distances – mais uniquement lorsque cet axe est logarithmique. Avec un axe de distance linéaire, la mise à l’échelle étire l’image polaire ; avec un axe de distance logarithmique, elle la décale d’une quantité fixe.

img.logpolar()

Les deux méthodes acceptent les mots-clés x= et y= qui définissent le centre de la reprojection polaire en coordonnées pixel de la source, avec pour valeurs par défaut respectivement la moitié de la largeur et la moitié de la hauteur de l’image. Le choix du centre est important : une transformation polaire autour du mauvais point aboutit à un contenu remanié de façons qui détruisent l’identité rotation / translation.

Trois panneaux alignés. Le plus à gauche est une image source cartésienne montrant un cadran d'horloge -- deux cercles concentriques avec douze repères autour du bord extérieur à des multiples de 30 degrés, et une seule aiguille pointant dans une direction. Le panneau central montre la reprojection linpolar de cette source : une image de sortie rectangulaire où les douze repères apparaissent comme des traits verticaux régulièrement espacés le long de la ligne du haut, les deux cercles concentriques apparaissent comme deux lignes horizontales à des positions verticales différentes, et l'aiguille de l'horloge apparaît comme une seule ligne verticale à la position correspondant à son angle dans la source. Le panneau de droite montre la reprojection logpolar : la même répartition angulaire le long de l'axe horizontal, mais avec l'écart entre le cercle intérieur et le cercle extérieur compressé parce que l'axe des distances est logarithmique.

Un cadran d’horloge reprojeté par linpolar() et logpolar(). Les cercles concentriques de la source deviennent des lignes horizontales dans la sortie ; les repères angulaires deviennent des lignes verticales régulièrement espacées le long de l’axe des angles. La variante log-polaire compresse l’espacement radial.

5.24.2. Quand recourir à chacune

Le choix entre linpolar() et logpolar() est le choix de l’invariance dont l’application a besoin. Pour la seule invariance en rotation – détecter que la même scène apparaît dans deux trames, la seconde tournée d’un angle inconnu – linpolar() suffit : la rotation devient un décalage horizontal dans l’image polaire, et un comparateur ne gérant que la translation comme find_displacement() récupère l’angle sous la forme de l’amplitude du décalage. Lorsque l”invariance d’échelle importe aussi – la seconde trame est tournée et zoomée – logpolar() ramène les deux inconnues à des translations : horizontale pour la rotation, verticale pour l’échelle.

C’est la recette standard d’un suiveur robuste aux changements de rotation et d’échelle : reprojeter la trame de référence et chaque trame en direct en log-polaire autour du même centre, exécuter find_displacement() sur la paire, et lire les champs rotation et scale du résultat.

5.24.3. Déroulage des caractéristiques circulaires

Un autre usage des transformations polaires est le déroulage de caractéristiques naturellement circulaires dans l’image. Un cadran d’horloge, un cadran de jauge, une cible d’inspection circulaire par conception – toutes deviennent linéaires dans la projection polaire, qui est la forme avec laquelle la plupart des algorithmes travaillent le plus facilement.

La figure ci-dessus le montre directement : les douze repères d’un cadran d’horloge, régulièrement espacés autour de la circonférence en cartésien, deviennent douze lignes verticales régulièrement espacées dans l’image polaire. Un rectangle autour de n’importe quel repère dans l’image polaire identifie la position de ce repère quelle que soit l’orientation du cadran d’horloge au moment de la capture. Un comparateur de modèle exécuté sur l’image polaire trouve chaque repère en une seule passe.

5.24.4. La transformation inverse

reverse=True exécute l’inverse de la projection polaire directe : à partir d’une image polaire, produit l’image cartésienne dont elle est la projection polaire. L’application appelle la forme directe pour exécuter un algorithme en coordonnées polaires, puis appelle la forme inverse pour reprojeter le résultat en cartésien pour l’étape en aval qui doit le voir.

L’usage le plus courant consiste à modifier une image polaire puis à la reprojeter : un filtre appliqué à l’image polaire – un lissage horizontal qui, en termes polaires, floute à travers les angles mais préserve la structure radiale – produit un résultat cartésien qui a été flouté angulairement, ce qu’un filtre cartésien ne peut pas faire directement.