TNI+VO · Exercice de Programmation

EP02_09 — 🧩 Transformation Affine Générique

2.12.9 EP02_09 🧩 Transformation Affine Générique

Dans cette activité, vous devez implémenter une transformation affine arbitraire sur une image. Cette opération est la généralisation de toutes les transformations linéaires (mise à l’échelle, rotation, cisaillement) combinées à la translation, permettant des manipulations géométriques complexes via une seule matrice.

  • Lisez deux entiers L et C, représentant les dimensions de la matrice.
  • Lisez six valeurs réelles (\(a, b, t_x, c, d, t_y\)) qui composent la matrice de transformation affine \(2 \times 3\).
  • Lisez une chaîne de caractères représentant la méthode d’interpolation (nearest ou bilinear).
  • Lisez les valeurs entières de la matrice d’origine.
  • Appliquez la transformation en conservant la taille d’origine \(L \times C\).
  • Affichez la matrice résultante.
  • Voir Figure 2.20 pour une simulation de cet EP.

📌 Important :

  • Mappage inverse : Pour calculer la valeur de chaque pixel dans l’image de destination, vous devez utiliser l’inverse de la matrice de transformation affine fournie afin de trouver la coordonnée correspondante dans l’image d’origine.
  • Remplissage : Les coordonnées calculées qui tombent hors des limites \([0, L-1]\) et \([0, C-1]\) de l’image d’origine doivent donner un pixel de valeur 0.
  • Flexibilité : Cette implémentation doit être capable d’effectuer n’importe laquelle des tâches précédentes (translation, rotation, etc.) en modifiant simplement les paramètres de la matrice.

Astuce :

flags = cv2.INTER_NEAREST if interp == 'nearest' else \
        cv2.INTER_CUBIC   if interp == 'bicubic'  else \
        cv2.INTER_LANCZOS4 if interp == 'lanczos' else \
        cv2.INTER_LINEAR

r = cv2.warpAffine(img, M, (C, L), flags=flags)

2.12.9.1 🧠 Combinaison d’opérations

La transformation affine préserve les points, les droites et les plans. En traitement d’images, elle mappe la position \((x, y)\) vers \((x', y')\) selon le système :

\[\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} t_x \\ t_y \end{bmatrix}\]

Ou, de manière compacte en coordonnées homogènes :

\[\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & b & t_x \\ c & d & t_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}\]

2.12.9.2 📋 Tâche (spécification pour VPL)

Entrée :

La première ligne contient L.

La deuxième ligne contient C.

La troisième ligne contient six flottants : a b tx c d ty.

La quatrième ligne contient la méthode interp (nearest ou bilinear).

Les lignes suivantes contiennent les éléments de la matrice \(L \times C\).

Sortie :

La matrice transformée avec les dimensions d’origine \(L \times C\).

2.12.9.3 📌 Exemples

Entrée Sortie Observation
2
2
1.0 0.0 0.5 0.0 1.0 0.5
bilinear
10 20
30 40
15 20
25 30
Translation fractionnaire \((t_x=0.5, t_y=0.5)\) : chaque pixel de sortie \((i,j)\) échantillonne la position \((i+0.5,\, j+0.5)\) de l’entrée via bilinéaire. Ex : \((0,0)\) interpole les quatre voisins \(→15\).
3
3
2.0 0.0 0.0 0.0 2.0 0.0
nearest
1 2 3
4 5 6
7 8 9
1 1 2
1 1 2
4 4 5
Mise à l’échelle \(2\times\) via matrice affine \((a=2, d=2)\) : chaque pixel de sortie \((i,j)\) échantillonne la position \((2i, 2j)\) de l’entrée avec le plus proche voisin. Ex : \((0,2)→(0,4)\) hors de l’image \(→\) le plus proche voisin découpe vers \((0,2)=3\)… en attente de confirmation de la logique de bord.
📐 Simulateur EP02_09 : Transformation affine 2D [x'] = [a b tx]·[x y 1]ᵀ

Ajustez les paramètres de la matrice affine 2×3 (rotation, échelle, cisaillement et translation) et observez l'effet appliqué sur la figure de référence.

Matrice affine 2×3
a b tx
c d ty

● Flèche orange (pointe triangulaire) + corps rectangulaire noir. La transformation affine est appliquée à la figure entière.

Matrice = [[1.0, 0.0, 0], [0.0, 1.0, 0]] → transformation identité.
Figure 2.20: Simulador EP02_09 : Transformação Afim 2D (Matriz 2×3)
%%writefile EP02_09.cpp
// your solution
Overwriting EP02_09.cpp
TestSuite("EP02_09.cpp").run()
✔️ EP02_09.cases existe déjà dans casos/
📋 5 cas chargé(s) depuis casos/EP02_09.cases

🔍 Test de C++ : EP02_09.cpp
⚠️ EP02_09.cpp : fichier vide (moins de 3 lignes). Tests ignorés.