Manipulation géométrique d'images avec OpenCV : Translation et Rotation

Les opérations de transformation géométrique constituent un pilier fondamental du traitement numérique d'images. OpenCV propose la fonction cv2.warpAffine() pour appliquer des mappages affines, permettant ainsi de déplacer ou de pivoter un cadre visuel tout en conservant les relations de parallélisme entre les lignes.

Visuel de référence utilisé dans les implémentations :

Image source de référenceDéplacement linéaire (Translation)

Le déplacement d'une image consiste à décaler chaque pixel selon un vecteur de translation donné. Mathématiquement, la nouvelle coordonnée (x', y') s'obtient via x' = x + Δx et y' = y + Δy. Cette opération se traduit par une matrice de transformation de taille 2x3 où les deux premières colonnes forment une matrice identité et la troisième contient les décalages.

import cv2
import numpy as np

def execute_translation(image_path, dx, dy):
    src = cv2.imread(image_path)
    if src is None:
        raise FileNotFoundError("L'image spécifiée est introuvable.")
    
    height, width = src.shape[:2]
    # Construction de la matrice affine 2x3 : [[1, 0, dx], [0, 1, dy]]
    matrix_shift = np.array([[1.0, 0.0, dx],
                             [0.0, 1.0, dy]], dtype=np.float32)
                             
    # Application du warp affine
    shifted_frame = cv2.warpAffine(src, matrix_shift, (width, height))
    return shifted_frame

if __name__ == "__main__":
    output = execute_translation("images/original.jpg", 80, 150)
    cv2.imshow("Reference", cv2.imread("images/original.jpg"))
    cv2.imshow("Deplacee", output)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Modification de l'orientation (Rotation)

La rotation d'une image s'effectue généralement autour d'un point central spécifique. Plutôt que de calculer manuellement les coefficients trigonométriques, OpenCV fournit cv2.getRotationMatrix2D() pour générer automatiquement la matrice affine requise.

import cv2

def rotate_frame(img_path, angle_deg, scale_val):
    original = cv2.imread(img_path)
    h, w = original.shape[:2]
    center_coords = (w // 2, h // 2)
    
    # Génération de la matrice de rotation
    rot_matrix = cv2.getRotationMatrix2D(center_coords, angle_deg, scale_val)
    transformed = cv2.warpAffine(original, rot_matrix, (w, h))
    return transformed

if __name__ == "__main__":
    result = rotate_frame("images/original.jpg", -35, 1.0)
    cv2.imshow("Initiale", cv2.imread("images/original.jpg"))
    cv2.imshow("Rotation", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Les paramètres attendus sont :

  • center : tuple (x, y) définissant le pivot de la rotation.
  • angle : valeur en degrés. Un positif entraîne une rotation antihoraire, un négatif une rotation horaire.
  • scale : facteur d'agrandissement ou de réduction appliqué simulatnément.

Mappage affine personnalisé

Lorsque les transformations standards ne suffisent pas, il est possible de définir une déformation arbitraire en spécifiant la correspondance entre trois points de l'image source et trois points cibles. La fonction cv2.getAffineTransform() calcule alors la matrice unique qui réalise cette projectino.

import cv2
import numpy as np

def apply_custom_affine(img_path):
    src_img = cv2.imread(img_path)
    h, w, _ = src_img.shape
    
    # Trois points de référence dans l'image originale
    origin_coords = np.float32([[0, 0], [w, 0], [0, h]])
    # Trois points cibles définissant la nouvelle géométrie
    target_coords = np.float32([[w * 0.15, h * 0.1], 
                                [w * 0.9, h * 0.25], 
                                [w * 0.2, h * 0.85]])
                                
    # Calcul de la matrice de mapping
    warp_mat = cv2.getAffineTransform(origin_coords, target_coords)
    return cv2.warpAffine(src_img, warp_mat, (w, h))

if __name__ == "__main__":
    final = apply_custom_affine("images/original.jpg")
    cv2.imshow("Originale", cv2.imread("images/original.jpg"))
    cv2.imshow("Transformee", final)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

La signature de la fonction de calcul est cv2.getAffineTransform(src, dst), où les arguments src et dst sont des tableaux NumPy de forme (3, 2) contenant respectivement les coordonnées des points d'entrée et de sortie. Une fois la matrice obtenue, elle est injectée directement dans cv2.warpAffine() pour produire l'image résultante.

Étiquettes: OpenCV Computer-Vision affine-transformation image-processing Python

Publié le 12 août à 11h13