• Aucun résultat trouvé

Fast Marching

Dans le document Algorithmique et Structures de Données (Page 48-52)

A.4 Fast Marching

Ce long TP nous occupera plusieurs séances. La première partie sera consacrée à l’implémentation de la file de priorité et nous l’utiliserons pour la résolution de l’équa-tion eïkonale, ce qui nous servira à calculer des cartes de distances sur des surfaces non homogènes.

A.4.1 Partie 1 : File de priorité

Pour stocker l’arbre binaire équilibré qui nous permet d’implémenter la file de prio-rité, il est très efficace d’utiliser un simple tableau. Pour une fois, nous considérerons que le premier élément du tableau est d’indice 1 et non 0. Le C++ n’autorise pas cela, mais plutôt que de jouer sur les indices, il est plus facile d’ignorer simplement l’indice 0 du tableau. La racine est donc en 1, ses enfants en 2 et 3, les enfants de 2 en 4 et 5 et ceux de 3 en 6 et 7, etc. Les enfants de l’élément d’indiceisont en2iet2i+1. Son parent en indicei/2(quotient de la division euclidienne). La façon d’effectuer les opérations pushetpopest rappelée figureA.8.

10

FIGUREA.8 – Procédurespush(haut) etpop(bas) de la file de priorité codée avec un arbre binaire.

1. Pour commencer, étudier le projet :

Télécharger le fichier FastMarching_Initial.zip sur la page habituelle, le décompresser.

2. Mise en place :

Écrire le constructeur et la méthodeempty. 3. Implémentation

Implémenter les fonctionspush et pop, suivant le principe de la figureA.8. La priorité est donnée par le champdistdePointDist. Attention, seule la compa-raison<est codée, donc votre code ne doit pas utiliser les opérateurs analogues, comme >, <=, >=, à moins que vous de les définissiez aussi. Pour intervertir deux variablesaetb, utilisez std :: swap(a,b).

4. Test

Danstest_priorite.cpp, mélangern = 20objetsPointDistde différentes priorités 0,1, . . . , n −1, les ajouter à une file de priorité, puis dépiler jusqu’au épuisement en affichant les priorités. Vous devriez trouvern−1, n−2, . . . ,0.

44

A. Travaux Pratiques A.4. Fast Marching

A.4.2 Intermède : équation eikonale

Algorithme de Dijkstra avec poids sur les nœuds

On utilisera un graphe dont les nœuds sont les pixels d’une image et les arêtes les relient à leux 4 voisins (moins de 4 sur les bords). Lorsque les poids sont affectés aux nœuds et non aux arêtes, l’algorithme de Dijkstra ne s’applique pas. Mais on peut s’y ramener par un graphe orienté avec poids différents pour les arêtes réciproques : w(p,q) =wq, et doncw(q,p) =wp. Comme toutes les arêtes arrivant en un même point ont le même poids, on ne retrouve pas dans la situation où un point a déjà une distance attribuée et on trouve plus tard un chemin plus court. Ainsi, il suffit de se souvenir quels pixels ont déjà été visités. On peut tester si Dp = ∞, ou bien en garder trace explicitement avec une tableE. Cela donne :

1. Initialiser toutes les distancesDp à l’infini, et un étatEp à false (non visité).

2. Mettre les points de départpdans une file de prioritéF avec priorité 0, fixer leur distanceDp = 0et leur étatEp =true.

3. p=F.pop(), et pour tous les voisinsqdepnon visités(Eq ==false) : (a) Dq =wq+ minp0∼q Dp0 (notez quepparticipe dans ce minimum).

(b) Eq ←true(point visité) (c) F.push(q,−Dq).

4. retourner en3siF n’est pas vide.

Cet algorithme, bien qu’exact, ne fonctionne pas pour une métrique non adaptée à un graphe : par exemple, si on place les nœuds sur les points de Z2, les points (0,0) et (1,1)sont calculés à distance2car les plus courts chemins passent par(1,0)ou(0,1).

Or pour la distance euclidienne, ils sont à distance√

2et le plus court chemin ne passe paspar des points de la grille.

Équation eikonale

Il s’agit de l’équation aux dérivées partielles (D:R2 →R+) :

|∇D|=W, D(S) ={0}

avecS ⊂ R2 et W > 0. S est l’ensemble des points de départ, à distanceD = 0, et W représente le coût d’entrée en un point. On peut mettre éventuellement une valeur+∞

pour empêcher l’accès à un point.

Par exemple, si on fixeW = 1partout, la solution est la fonctionD(x) = dist(x, S). Fast marching

Il s’agit d’une solution approchée sur une grille de l’équation eikonale faisant inter-venir une modification simple de l’algorithme de Dijkstra. Pour cela, il faut utiliser un bon schéma numérique pour le gradient :

(|∇D|)2i,j = max(Di,j−Di,j+1, Di,j−Di,j−1,0)2+ max(Di,j−Di+1,j, Di,j−Di−1,j,0)2. Si on cherche à mettre à jourDi,jconnaissantDaux quatre voisins de(i, j), on obtient :

(Di,j = min(d1, d2) +Wi,j sid1 = +∞oud2 = +∞

(Di,j−d1)2+ (Di,j −d2)2 =Wi,j2 sinon, (A.3)

A.4. Fast Marching A. Travaux Pratiques

avecd1 = min(Di,j+1, Di,j−1) etd2 = min(Di+1,j, Di−1,j). Le deuxième cas de l’alterna-tive donne une équation polynômiale de degré 2 dont la solution est :

Di,j =

d1+d2+q

2Wi,j2 −(d1−d2)2

2 , (A.4)

l’autre racine conduisant à une valeur inférieure à d1 ou d2. Si le discriminant (sous la racine carrée) est négatif, on applique la formule du premier cas. Le fast marching remplace donc simplement l’étape3ade l’algorithme de Dijkstra par (A.4) dans le cas où cette formule s’applique (discriminant positif).

Dans les programmes interactifs ci-dessous, guidez l’utilisateur sur ce qui est at-tendu de lui par des std :: cout.

A.4.3 Partie 2 : carte de distance

1. Complètez la fonctionfastMarching. Elle fait appel à calcDistance appli-quant (A.3), qui elle-même appelleminVoisins, également à complèter.

2. Dans distancePoint.cpp, faites entrer à l’utilisateur des points de départ, puis afficher la carte de distance à ces points. Utilisez la fonctionaffichepour montrer l’image des distances en couleurs (bleu=0, rouge=maximum).

FIGURE A.9 – Points de départ et carte de distance à ces points dans le programme distancePoint

A.4.4 Partie 3 : ombres

3. Dans le programme ombres.cpp, faites dessiner à l’utilisateur des rectangles représentant des objets opaques (utilisez la fonctionselectionRect). Remplir dans l’imageI les pixels du rectangle en rouge.

4. Faites cliquer à l’utilisateur une position de source lumineuse, assurez-vous que ce ne soit pas un point rouge.

5. Remplissez la carte de coût Wavec avec des valeurs infinies là où l’image I est rouge. Unfloatpeut prendre la valeur infinie, définie par la constanteINFdans fastMarching.h. Les calculs impliquant des valeurs infinies se comportent comme on peut s’y attendre ; les opérations mal définies, comme∞ − ∞et0∗ ∞ donnent un NaN (“not a number”).

46

A. Travaux Pratiques A.4. Fast Marching

6. L’idée est de calculer les ombres en calculant la carte des distancesDavec com-portant les obstacles et Dsans en l’absence d’obstacles. Là où Davec excède Dsans(avec une toléranceTOL), marquer une ombre en bleu.

7. Affichez les cartes de distance avec/sans obstacles dans des fenêtres séparées.

FIGUREA.10 – Ombres portées depuis la source lumineuse placée au point vert, cartes de distance avec et sans obstacles, dont la comparaison a permis le calcul des ombres.

A.4.5 Partie 4 : Géodésique

On va chercher un plus court chemin en suivant au mieux la couleur du pixel de départ.

8. Le point de départ p étant désigné par l’utilisateur, la carte de coût se calcule suivant la formule

W(q) = +kI(q)−I(p)k1/3

avec la constante = 10(règle la rectitude de la géodésique). Cette fonction croît avec la différence de couleur, donc encourage à rester à la couleur du pixel de départ.

9. Pour éviter des risques de sortie de l’image, mettre lesW(q)à+∞quandqest au bord de l’image.

10. La fonctiongeodesiqueretourne un vecteur donnant le plus court chemin entre les pointsp1 etp2 : on part dep2et on descend dans la direction du gradient :

qi+1 =qi− τ

|∇D|∇D.

On arrête dès que|qi−p1|<1, et on ajoutep1. Cependant, on restreindra la géo-désique à un nombre maximum de points. Au cas où on n’arrive pas à proximité dep1 au bout de ce nombre de points, on affiche un message d’avertissement à l’utilisateur.

11. Faites cliquer à l’utilisateur des points de départ et d’arrivée sur la carte des coûts, et tracez le chemin géodésique.

A.4. Fast Marching A. Travaux Pratiques

FIGURE A.11 – Tracé de géodésique : image initiale, géodésique vers le point blanc, image de coût par rapport au point de départ (en vert), image de distance à ce point.

48

Dans le document Algorithmique et Structures de Données (Page 48-52)

Documents relatifs