M1 synthèse d'images
2023

TP1 - images

Installation

installez la base de code minimaliste gKit3 sans dépendances.

lisez le readme sur la forge et compilez tp1.

si vous souhaitez un aperçu des fonctions nécessaires pour réaliser le tp, vous pouvez consulter la doc sur les points et les vecteurs. ainsi que celle sur les images + les couleurs.


Partie 1 : et en 2D, comment ça marche ?

on sait changer la couleur d'un pixel d'une image :

Image image(512, 512);

image(10, 10)= Red();    // le pixel (10, 10) est rouge
image(20, 20)= Color(rouge, vert, bleu);    // avec rouge, vert et bleu des reels entre 0 et 1


exercice 1 :
comment dessiner une forme géométrique ? un disque de centre c et de rayon r, par exemple.
on va s'interesser à une solution très simple : pour chaque pixel de l'image, on le colorie s'il est à l'intérieur du disque.

étape 1 : parcourir tous les pixels de l'image :

Image image(512, 512);

for(int y= 0; y < image.height(); y++)
for(int x= 0; x < image.width(); x++)
{
    Color color= White();
    pixel(x, y)= color;
}

étape 2 : comment déterminer que le pixel p est à l'intérieur du disque ?
il suffit de se rappeler qu'un point p fait partie d'un disque (ou d'une sphère en 3d) s'il se trouve à une distance du centre inférieure au rayon du disque.

faites le test et coloriez le disque. quelques couleurs sont prédéfinies dans color.h

remarques : vous pouvez utiliser la structure Point pour manipuler les coordonnées d'un pixel, il faudra juste z= 0. la fonction distance(p, q) renvoie la distance entre 2 points p et q.
Point p= { x, y, 0 };
Point p= Point( x, y, 0 );  // les 2 syntaxes sont possibles...
float d= distance(p, q);    // distance entre p et q

exercice 2 :
si on souhaite maintenant dessiner un anneau ?


exercice 3 :
et si l'épaisseur de l'anneau est 1 ou 2 pixels, que se passe-t-il ?
et si on testait plusieurs points, à l'intérieur du pixel, au lieu de ne tester que le centre ? peut-on dessiner une forme aussi "fine" ?

rappel : on peut aussi calculer une image plus grande, la filtrer et la sous-échantilloner, c'est équivalent mais plus long à faire.

et sur le disque ou un anneau classique, l'image change-t-elle ?


exercice 4 :
et pour un triangle de sommets a, b et c ? comment peut-on vérifier qu'un pixel p se trouve à l'intérieur du triangle ? on va suivre le même principle, pour chaque pixel de l'image, on vérifie s'il appartient ou pas au triangle.
on peut décomposer ce test en 3 parties : si le pixel se trouve du "bon" coté de chaque arete du triangle, il est à l'intérieur.

comment formuler le test sur une arete ?

on peut utiliser un produit scalaire.
on veut savoir de quel cote de l'arete ab se trouve le vecteur ap. il suffit de calculer le produit scalaire entre le vecteur ap et un vecteur perpendiculaire à l'arete ab.
on recommence le test pour les autres aretes du triangle : ab, bc, ca (oui c'est orienté, et c'est important !)
rappel : produit scalaire en 2D de 2 vecteurs u et v : dot(u, v) = u.x * v.x + u.y * v.y
rappel : vecteur perpendiculaire du vecteur u = (-u.y, u.x)

on peut aussi calculer l'aire signée d'un triangle.
c'est le même test mais formulé avec une autre propriété. quelle est l'aire algébrique (signée) du triangle abp ? du triangle bcp ? et cap ? du triangle abc ? si les 4 aires ont le même signe, le pixel p est à l'intérieur du triange.

l'aire signée d'un triangle est le déterminant de la matrice construite avec les coordonnées des sommets.
rappel : calculer le determinant d'une matrice 2x2 et 3x3, cf wikipedia
rappel : comment construire la matrice 2x2 ? c'est le paragraphe suivante dans wikipedia. ah et l'aire d'un parallelograme est le double de celle d'un triangle... (et de même signe...)

pour les curieux : vérifiez que les 2 formulations sont très exactement identiques !!

pour les curieux : on peut écrire le test très facilement, mais en 3d (la composante z sera nulle) en vérifiant que le produit vectoriel de ab et ap est orienté dans le même sens que la normale du triangle abc... il faut bien sur tester aussi les aretes bc, et ca.