> Modules non standards > OpenCV > Transformations géométriques
Transformations géométriques
Image de départ :
newImg = img
Transformations simples :
- newImg = cv2.flip(img, 0) : renverse l'image haut-bas (1 pour gauche-droite, -1 pour les deux en même temps)
- newImg = cv2.transpose(img) : transposition (échange de l'axe des x et des y).
Mise à l'échelle / changement de taille :
- newImg = cv2.resize(img, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC) : resizing de x 0.5 dans les deux dimensions.
- newImg = cv2.resize(img, (img.shape[1] / 2, img.shape[0] / 2), interpolation = cv2.INTER_CUBIC) : resizing de x 0.5 dans les deux dimensions.
- types d'interpolations possibles sont :
- cv2.INTER_NEAREST : le plus proche voisin.
- cv2.INTER_LINEAR : interpolation bilinéaire (le défaut).
- cv2.INTER_CUBIC : interpolation bicubique (plus précise, mais plus coûteuse).
Exemple de changement d'échelle :
newImg = cv2.resize(img, None, fx = 1, fy = 0.5, interpolation = cv2.INTER_CUBIC)
Rotation :
- on crée d'abord la matrice de transformation 2 x 3 : transfoMatrix = cv2.getRotationMatrix2D((img.shape[0] // 2, img.shape[1] // 2), 20, 0.8) :
- (img.shape[0] // 2, img.shape[1] // 2) est le centre de rotation (ici, le centre de l'image).
- 20 est l'angle de rotation dans le sens trigonométrique en degrés.
- 0.8 est l'échelle. Mettre 1 pour ne pas changer d'échelle, < 1 pour diminuer de taille, > 1 pour augmenter de taille.
- puis, on applique cette matrice : newImg = cv2.warpAffine(img, transfoMatrix, None)
- on peut indiquer la méthode d'interpolation : cv2.warpAffine(img, transfoMatrix, None, flags = cv2.INTER_CUBIC) : interpolation bicubique utilisée.
- on peut indiquer quelle méthode doit être utilisée pour les bordures non remplies :
- newImg = cv2.warpAffine(img, transfoMatrix, None, borderMode = cv2.BORDER_CONSTANT) : constant et noir (le défaut).
- newImg = cv2.warpAffine(img, transfoMatrix, None, borderMode = cv2.BORDER_CONSTANT, borderValue = (255, 255, 0)) : constant et cyan (attention, la couleur est donnée sous forme (B, G, R)).
- cv2.BORDER_REPLICATE : prend la dernière couleur fixée et l'étend perpendiculairement (donne des lignes perpendiculaires).
- cv2.WRAP : utilise les pixels opposés pour compléter de manière circulaire (pixels de gauche pour complèter à droite par exemple).
- cv2.REFLECT : complète les bordures par reflexion.
Exemple de rotation en diminuant la taille et avec reflexion sur les bordures pour les endroits qui sont vides après rotation :
transfoMatrix = cv2.getRotationMatrix2D((img.shape[0] // 2, img.shape[1] // 2), 30, 0.8)
newImg = cv2.warpAffine(img, transfoMatrix, None,
flags = cv2.INTER_LINEAR,
borderMode = cv2.BORDER_REFLECT)
Transformation affine :
- définie par une matrice 3 x 2. Elle transforme ainsi le point (x, y) en point (x', y') avec x' = ax + by + e et y' = cx + dy + f, avec comme matrice :
a b e
c d f
- les transformations affines permettent de faire des mises à l'échelle, des rotations, des translations, ces cisaillements et toutes les combinaisons de ces transformations.
- on peut effectuer une transformation affine simplement en donnant la matrice :
transfoMatrix = numpy.array([[1, 0.5, 0], [0, 1, 0]], dtype = numpy.float32)
newImg = cv2.warpAffine(img, transfoMatrix, None)
- une transformation affine est aussi totalement déterminée par la transformation de 3 points du plan (ainsi que les 3 points d'origine), car cela donne alors 6 équations et il y a 6 inconnues.
- exemple de calcul d'une matrice de transformation affine avec 3 points et leurs transformés : transfoMatrix = cv2.getAffineTransform(numpy.array([[0, 0], [10, 0], [0, 10]], dtype = numpy.float32), numpy.array([[0, 0], [10, 0], [5, 10]], dtype = numpy.float32)). Attention : les points doivent être donnés sous forme (x, y), x horizontal et y vertical et non pas l'inverse !
- une fois qu'on a la matrice, il suffit de l'utiliser comme ci-dessus.
- on peut indiquer un algorithme d'interpolation et une façon de remplir les bordures non remplies, comme pour la rotation ci-dessus.
Exemple transformation affine :
import numpy
transfoMatrix = cv2.getAffineTransform(numpy.array([[0, 0], [10, 0], [0, 10]],
dtype = numpy.float32),
numpy.array([[0, 0], [10, 0], [5, 10]],
dtype = numpy.float32))
newImg = cv2.warpAffine(img, transfoMatrix, None)
On peut inverser une transformation affine :
- transfoMatrixInv = cv2.invertAffineTransform(transfoMatrix)
- si on applique une transformation affine sur une image, puis son inverse sur le résultat, on obtient l'image de départ, dans les zones traitées par les transformations (en dehors des bords perdus).
exemple : inversion de la transformation affine ci-dessus :
transfoMatrix = cv2.getAffineTransform(numpy.array([[0, 0], [10, 0], [0, 10]],
dtype = numpy.float32),
numpy.array([[0, 0], [10, 0], [5, 10]],
dtype = numpy.float32))
transfoMatrix = cv2.invertAffineTransform(transfoMatrix)
newImg = cv2.warpAffine(img, transfoMatrix, None)
Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert