5.21. Mise à l’échelle, retournement et recadrage¶
Les sous-sections précédentes travaillaient toutes sur les pixels aux positions où ils se trouvaient au départ. La famille des transformations change cela. La mise à l’échelle envoie chaque pixel d’entrée vers une position de sortie différente, possiblement vers plusieurs positions de sortie à la fois (lors d’un agrandissement) ou vers une position partagée avec plusieurs autres pixels d’entrée (lors d’une réduction). Le retournement et la rotation font la même chose au moyen d’une correspondance différente. Le recadrage conserve un sous-ensemble rectangulaire de pixels d’entrée et écarte le reste.
Le module image expose cette famille à travers trois méthodes qui partagent la plupart de leurs arguments et la plupart de leur comportement :
copy()– produit une copie de l’image, éventuellement mise à l’échelle, recadrée ou réorientée.crop()– la même opération quecopy, mais avec l’idée que l’application va sélectionner un sous-rectangle dans la source.scale()– la même chose encore, avec l’idée que l’application va redimensionner le résultat.
Les trois partagent les mêmes arguments et le même mécanisme de transformation ; la différence réside dans l’endroit où atterrit le résultat par défaut. copy() produit une nouvelle image, tandis que crop() et scale() modifient la source sur place.
5.21.2. Interpolation : AREA, BILINEAR, BICUBIC¶
Lorsque la mise à l’échelle envoie chaque pixel de sortie vers une position qui ne s’aligne sur aucun pixel d’entrée unique, la méthode doit choisir quelle valeur écrire. Trois indicateurs contrôlent comment :
image.BILINEAR interpole entre les quatre pixels d’entrée les plus proches, pondérés par leur distance par rapport à la position de sortie. Le résultat est plus lisse que le plus proche voisin, sans crénelage visible sur les lignes diagonales, mais le calcul supplémentaire coûte environ quatre fois la passe du plus proche voisin. Le bon choix pour la plupart des travaux d’agrandissement et pour tout facteur d’échelle non entier.
image.BICUBIC interpole entre les seize pixels d’entrée les plus proches à l’aide d’une courbe cubique, ce qui produit des résultats encore plus lisses au prix d’un calcul plus important encore. La meilleure qualité pour les applications sensibles au coût qui en ont besoin ; rarement utile au regard du calcul supplémentaire pour des trames en direct que l’IDE ne fera qu’afficher.
image.AREA moyenne chaque pixel d’entrée qui tombe à l’intérieur de l’empreinte du pixel de sortie – le bon algorithme pour la réduction. Le bilinéaire et le bicubique sont des interpolateurs : ils estiment une valeur entre les pixels source, ce dont l’agrandissement a besoin, mais lors d’une réduction chaque pixel de sortie couvre de nombreux pixels source et un interpolateur n’en lit que les quelques plus proches – le détail qu’il ignore revient sous forme de crénelage. image.AREA intègre à la place chaque pixel couvert dans la moyenne.
L’algorithme de mise à l’échelle par défaut sans aucun indicateur est le plus proche voisin, qui est le moins coûteux et la bonne réponse lorsque la source est déjà à la résolution en pixels de la destination.
5.21.3. Orientation : retournements et rotations¶
Les indicateurs d’orientation sont un petit ensemble de transformations booléennes qui se composent librement entre elles et avec les indicateurs d’interpolation :
image.VFLIPretourne l’image verticalement (le haut devient le bas).image.HMIRRORla met en miroir horizontalement (la gauche devient la droite).image.TRANSPOSEéchange les axes x et y (les lignes deviennent des colonnes).
La plupart des rotations proviennent de la composition de ces trois opérations. Le module expose également des raccourcis nommés :
image.ROTATE_90(=VFLIP | TRANSPOSE)image.ROTATE_180(=HMIRROR | VFLIP)image.ROTATE_270(=HMIRROR | TRANSPOSE)
En code :
img.copy(hint=image.ROTATE_90, copy_to_fb=True)
5.21.4. Gestion du rapport d’aspect¶
Lorsque le rapport d’aspect de la source ne correspond pas au rectangle dans lequel elle est dessinée, trois indicateurs décident quoi faire de cet écart :
image.SCALE_ASPECT_KEEP préserve le rapport d’aspect de la source et ajoute des bandes noires au résultat – la source est mise à l’échelle jusqu’à ce qu’elle tienne à l’intérieur de la destination, les pixels vides (zéro) remplissant le reste de la destination. Le bon choix lorsque conserver la source sans distorsion importe plus que remplir toute la sortie.
image.SCALE_ASPECT_EXPAND préserve le rapport d’aspect de la source et la recadre – la source est mise à l’échelle jusqu’à ce qu’elle remplisse la destination, les parties qui dépassent la destination étant coupées. Le bon choix lorsque remplir toute la sortie importe plus que voir chaque partie de la source.
image.SCALE_ASPECT_IGNORE ignore le rapport d’aspect et étire la source pour remplir la destination, en acceptant toute distorsion ainsi introduite. Le bon choix lorsque l’application a déjà tenu compte de la distorsion – lorsque les dimensions de la destination ne constituent pas réellement un rectangle de la même scène, par exemple.
La valeur par défaut (aucun indicateur d’aspect défini) est la même que SCALE_ASPECT_IGNORE : étirer pour remplir. Les applications soucieuses du rapport d’aspect en spécifient explicitement l’un des trois.
5.21.5. Quand recourir à laquelle¶
La plupart des redimensionnements utilisent scale() avec une paire x_scale / y_scale et un indicateur d’interpolation :
img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)
La plupart des rotations utilisent le même appel avec hint=image.ROTATE_90 ou similaire.
Le recadrage utilise crop() avec un roi non par défaut :
img.crop(roi=(40, 30, 200, 150))
Lorsque la source doit survivre à l’opération – capturer une trame de référence, prendre une miniature d’une trame sur le point d’être traitée de manière destructive – copy() produit le résultat sous forme de nouvelle image et laisse la source intacte :
thumbnail = img.copy(x_scale=0.25, y_scale=0.25, hint=image.AREA)
Cette valeur par défaut est la vraie différence derrière les trois noms : scale et crop transforment sur place, copy alloue. Les mots-clés de placement du résultat comblent l’écart : copy=True sur scale ou crop alloue le résultat dans un tampon de tas distinct au lieu d’écraser la source, et copy_to_fb=True sur l’une quelconque des trois le place dans le tampon d’image pour l’aperçu de l’IDE.