Micmac – Tutoriel de photogrammétrie sous windows


1  Introduction

MicMac est un logiciel libre de photogrammétrie, permettant de réaliser des nuages de points 3D à partir de photos. Il a été créé initiallement par Marc Pierrot Deseilligny de l’IGN, et continue a être développé actuellement, notamment dans le cadre de projets de recherche (Culture 3D Cloud, Monumentum). Sa licence permet une utilisation libre en échange d’une obligation de citation (voir les détails de la licence CeCILL-B sur le site de l’IGN).
Ce tutoriel fait pendant à un autre tutoriel pour MicMac adressé aux débutants et publié en 2013 sur le site Combien ça porte. Le tutoriel proposé ici s’adresse aux personnes qui connaissent déjà MicMac et l’utilisent sous windows. Il intègre l’utilisation des nouveaux outils intégrés à MicMac et qui en simplifient l’utilisation (création interactive des masques 2D et 3D avec SaisieMasqQt, création automatique du nuage de point avecC3DC), ou qui en étendent les fonctions (filtrage des points homologues avec Schnaps et HomolFilterMasq). Une partie importante de ce tutoriel est dédiée à la recherche de l’orientation des photos (options avancées avec Tapas et Campari).
Ce tutoriel utilisera un script batch pour automatiser les différentes étapes de MicMac sous windows. Ce script est prévu pour être adaptable à des situations non standards (photos mal calibrées, photos avec faible recouvrement).
Pour les utilisateurs débutants de MicMac, il sera probablement nécessaire de se faire la main dans un premier temps avec l’interface graphique disponible depuis 2015, et qui est fournie avec le package d’installation de MicMac. Les prérequis pour ce tutoriel sont :
  • une connaissance de base de MicMac et des principes de la photogrammétrie
  • une connaissance de base des languages de programmation (concept de variables, de paramètres des programmes en ligne de commande)
  • de la patience
Pour mémoire, les étapes principales pour la construction d’un nuage de points avec MicMac, et les outils utilisés sont :
  • calcul des points clés des photos : Tapioca
  • détermination de la calibration intrinsèque de l’appareil photo dans le réglage qui a servi à faire les photos à la base du nuage de point (étalonnage), et l’orientation relative des photos : Tapas, Martini, Campari
  • en option, tri des points homologues : HomolFilterMasq, Schnaps
  • corrélation entre une image maîtresse et ses images filles pour créer une carte de profondeur : Malt, AperoChImSecMM
  • création d’un nuage de points et sa coloration : Nuage2Ply

2  Rappels sur les prises de vues

Avant de commencer avec le vif du sujet, rappelons que les prises de vues doivent répondre à des règles précises pour faciliter le traitement des images avec MicMac. Si ces règles ne sont pas respectées, il devient plus difficile (mais pas impossible) d’obtenir des résultats.
Il est préférable de fixer une fois pour toute les paramètres suivants au début de la séance de prise de vues :
  • longueur focale (ou éventuellement ne travailler qu’avec 2 ou 3 longueurs focales pour éviter les difficultés pour la calibration lors de l’utilisation de Tapas, c’est-à-dire la calibration et orientation des images)
  • mise au point (désactiver autofocus). Attention, certains appareils proposent une mise au point automatique « de sécurité », qui se déclenche avant la prise de vue pour régler plus finement la mise au point manuelle si besoin est. Il faut désactiver cette fonctionnalité si elle existe sur l’appareil.
  • désactivation de la stabilisation
  • balance des blancs (ne pas utiliser automatique)
Lors de la séance de prises de vues, il faut jouer entre l’ouverture du diaphragme, le temps de pose, et la sensibilité ISO du capteur pour avoir des photos nettes, bien exposées, sans bruit (si la sensibilité ISO est trop élevée) avec une profondeur de champ adaptée au sujet étudié.
Concernant l’exposition, il est possible de surexposer le ciel qui n’est pas utile (et même un obstable) pour la génération du nuage de point.
Il est généralement recommandé dans les guides concernant la photogrammétrie d’utiliser un appareil numérique reflex, mais il est en réalité possible d’utiliser un appareil compact, du moment que les photos sont nettes et bien exposées. Il est même possible désormais d’utiliser des photos prises sans controle du focus (avec autofocus enclenché). Dans ce dernier cas le traitement des photos sera un peu plus complexe (calibrage image par image présenté ci-dessous).
Concernant le format des photos, il faudrait travailler en toute rigueur avec des photos au format raw, ou aucune perte d’information (compression, nombres de couleurs) n’est à craindre. Cependant pour un usage amateur de MicMac, les photos au format jpg permettent d’obtenir des résultats déjà satisfaisants.

3  Installation

Le fichier zip contenant une version compilée (prête à l’emploi) des binaires Windows est disponible sur la page de l’IGN consacrée à MicMac. Le programme d’installation de micmac créera le dossier à la racine de votre disque dur (du type C:/MicMac64bits).
Il vous faudra ensuite installer les packages suivants s’ils n’existent pas déjà sur votre ordinateur : Le fichier C:/micmac/LISEZMOI contient des indications complémentaires relatives à l’installation si les indications précédentes étaient insuffisantes.
Note pour utilisateurs avancés : il est possible d’utiliser pour un même projet plusieurs versions différentes de MicMac sur un même PC, en indiquant les liens vers le répertoire bin de chaque version (ligne set BIN_DIR=C:/MicMac64bits6706/bin dans le script ci-dessous).
Dernier avertissement : la version windows de MicMac est moins stable que celle sous Linux, et il est conseillé par les créateurs du logiciels d’utiliser Linux. Si malgré tout vous ne pouvez pas utiliser Linux, ce tutoriel est fait pour vous.

4  Script batch pour MicMac sous windows

4.1  Préalable

L’ensemble des commandes de MicMac seront executés depuis un fichier batch, contenant le script des commandes. Ce fichier est téléchargeable ici, et son contenu est donné également à la fin de l’article. Il a été développé pour la version x64 rev6706 de MicMac (2016).
Copier le fichier dans un dossier C:/micmac_data/nom_projet1 et renommer son extension de txt en bat. Copier l’ensemble des photos dans ce même répertoire. La première partie du fichier correspond aux options à modifier pour indiquer les répertoires d’installation de MicMac et Meshlab (si disponible), la description du nom des images, etc. Le reste du script est donné par phases, que nous allons détailler une à une dans la suite.
Pour pouvoir facilement activer ou désactiver certaines phases, des switchs sont intégrés au script. Par exemple, utiliser set DoPhase1=true pour activer la phase 1 (recherche des points clés). Lorsque le script sera relancé (par exemple lorsque vous rechercherez une meilleure orientation), utiliser set DoPhase1=false pour ne pas relancer à nouveau le programme de la phase 1.
On rappelle les points principaux pour l’utilisation du fichier batch :
  • les lignes de commentaire commencent par ::, les commentaires en fin de ligne commencent pas & REM
  • l’opérateur set permet de définir les variables. Chaque variable est appelée par son nom entouré par %, ou par ! à l’intérieur des boucles for et if
  • ne pas utiliser de exit pour sortir prématurément du script, car cela empécherait la bonne lecture des fonctions dos prédéfinies en pied de page du script. Utiliser la commande pause & goto:eof à la place de exit.
  • la commande dos help macommande vous donnera sur la console les informations relatives à la commande dos macommande (pour l’aide avec les commandes MicMac taper mm3d macommande help)
  • on évitera les accents et les espaces dans les noms de répertoire et de fichier
  • on évitera de sauter ou de commenter des lignes au milieu d’un bloc de commande délimité par les parenthèses
Les quatre phases de calcul contenues dans le script sont décrites maintenant.

4.2  Phase 1 – Recherche des points clés et des correspondances

Le programme Tapioca recherche les points-clés (tie points avec algorithme Sift) puis les correspondances entre ces points-clés, également appelés points homologues (ou matches). Ces informations sont stockées dans le répertoire Homol et réutilisées dans la suite pour trouver l’orientation des photos.
Tapioca est lancé dans le script avec l’option MulScale : la recherche des correspondances est faite sur des images réduites à 300 pixels (rapide), puis à 800 pixels pour les couples d’images qui présentes des correspondances à 300 pixels. D’autres possibilités sont présentées dans les variantes plus loin dans le tutoriel. Attention utiliser une résolution élevée est couteux en temps de calcul.
Il est peut-être possible d’améliorer la précision de la recherche de l’orientation, en remplaçant la valeur 1000 (qui correspond à la plus grande dimension des images) par une valeur plus élevée, et en produisant ainsi plus de points-clés et de correspondances. Cependant la valeur la plus souvent utilisé dans les exemples de la documentation de MicMac est autour de 1000 (800 – 1500). Peut-être n’y-a-t-il pas d’intérêt particulier à augmenter cette valeur. Dans un article consacré à MicMac, Friedt indique à ce sujet 1: ,,Il semble accepté que la plus haute résolution soit de l’ordre du tiers à la moitié de la résolution des photographies ».
Ajouter paramètre Detect=digeo à Tapioca pour utiliser l’algorithme digeo au lieu de sift pour la recherche des points homologues. La documentation de MicMac indique que digeo est plus rapide, mais a été moins testé que sift qui est utilisé par défaut.
Les dossiers créés par Tapioca lors de cette phase sont : Tmp-MM-Dir qui contient notamment informations tirées de l’exif des photos, Pastis qui contient les informations des points-clés, Homol et Homol_SRes (si utilisation MulScale) pour le stockage des correspondances (points homologues).

4.3  Phase 2 – Calibration intrinsèque des objectifs et Orientation relative des images

Pour faciliter l’explication de la suite, nous supposons que toutes les photos ont été prises avec un seul appareil photo (Canon_PowerShot_S110), deux longueurs focales (ou niveau de zoom) que nous appelons par simplicité objectifs dans la suite : un objectif 5.2mm et un objectif 10.8mm. Pour chaque objectif une seule et même mise au point (focus) a été utilisé lors des prises de vues. Par conséquent toutes les photos prises avec un objectif partagent (théoriquement) les mêmes caractéristiques.
L’appel à la fonction Tapas sur l’ensemble des photos va rechercher :
  • les paramètres de l’objectif 5.2mm (longueur focale exacte, point principal, paramètres de distortion, etc.), qui seront ensuite stoquées dans le fichier AutoCal_Foc-5200_Cam-Canon_PowerShot_S110.xml ;
  • les paramètres de l’objectif 10.8mm qui seront ensuite stoquées dans le fichier AutoCal_Foc-10800_Cam-Canon_PowerShot_S110.xml ;
  • l’orientation relative des photos, c’est à dire la position dans l’espace et la direction de l’objectif au moment de chaque prise de vue, qui sera stockée dans les fichiers Orientation-XXXX.xml avec XXXX le nom de chaque image.
L’ensemble de ces fichiers sera enregistré dans un répertoire dont le nom commencera systématiquement par le préfixe Ori-. Les fichiers de ce répertoire décrivent entièrement l’orientation et la calibration des photos telle que calculée par Tapas pour cette étape.
Il faut indiquer à Tapas le type de modèle qui sera utilisé pour décrire chaque objectif. Pour les appareils compacts utiliser RadialBasic, et éventuellement dans un deuxième temps RadialStd ou RadialExtended.
Les options suivantes sont possibles :
  • L’option facultative SauvAutom=NONE permet de ne pas sauver les résultats de chaque itération de l’orientation dans Tmp-MM-Dir.
  • L’option facultative SH=!SH! indique le suffixe du répertoire Homol contenant les correspondances (!SH! est une variable dos qui contiendra "", "_mini" ou "HomolMasqFiltered" suivant les cas)
Une fois la calibration et l’orientation calculés (ce qui n’est pas toujours facile, nous reviendrons longuement sur ce point dans la suite), l’appel à AperiCloud créé le nuage de point 3D représentant les points clés dans l’orientation calculée et la position des objectifs. Ce nuage sera ouvert avec Meshlab si le programme est installé. Il est possible de ne générer que la position des prises de vues en utilisant l’option WithPoints=0 avec AperiCloud.
Le nuage de points de AperiCloud permet de vérifier visuellement le succès ou non du processus d’orientation. MicMac fourni également des informations tout au long des calculs : le résidu moyen, et le pourcentage de correspondances de chaque photo qui sont prises en compte. Le résidu moyen devrait être inférieur à 1.0 pour toutes les photos dans une orientation réussie2 (généralement entre 0.5 et 1.0). Si une photo a un résidu supérieur à 1 à la fin du processus, elle est probablement mal orientée. De plus, le pourcentage (ou taux) des correspondances devrait être supérieur à 90%. En effet Tapas rejette au cours du calcul les fausses correspondances (outliers) : pour simplifier, il s’agit des points-clés très similaires qui semblaient correspondre à des objets identiques, mais qui en fait sont situés en deux points de l’espace différents (par exemple dans le cas d’un motif répétitif sur une photo en plusieurs endroits). Nous reviendrons sur le calcul du résidu plus loin.
Il est également possible que l’ensemble des photos soient bien orientées sauf quelques unes, et il faut donc vérifier le résidu maximum, et l’évolution maximum (à la dernière étape du calcul de compensation), pour voir si la recherche a convergé.
Attention, lancer Tapas sur un faible nombre de photo (par exemple 3) ou avec des photos présentant un faible recouvrement peut donner d’excellents résultats (résidu proche de 0.6 et taux de 98%) et pourtant donner une calibration et orientation approximative, qui se manifeste par un nuage de point légèrement déformé par rapport à la forme attendue, ou une photo mal placée par rapport à la position de la prise de vue (par exemple quand toutes les photos ont été prises depuis le niveau du sol, mais que l’une d’elle apparait quelques mètres au dessus des autres). Le résidu et le taux sont donc des conditions nécessaires, mais non suffisantes pour signifier la réussite de la calibration des objectifs et de l’orientation des photos, et la vérification du résultat avec Apericloud est fortement conseillée après chaque utilisation de Tapas ou Campari (que nous verrons dans la suite).

4.4  Phase 3 – Affinage de la calibration et de l’orientation

La calibration et l’orientation trouvées ci-dessous se trouve dans le répertoire Ori-Ori001_RadialBasic. Cette première orientation (au sens calib+orientation) n’est pas nécessairement optimale dès le premier coup, et il existe plusieurs outils pour améliorer cette orientation. Les outils proposés dans le script peuvent s’activer en mettant true sur les lignes DoPhase4XXXX=false.
Pour faciliter l’utilisation de ces outils, qui vont créer à chaque fois un nouveau dossier d’orientation, on utilise l’appel à la fonction dos SetOriVar définie à la fin du fichier script. Cet appel call:SetOriVar "_MyComment" charge dans les variables dos !OriIn! et !OriOut! respectivement la dernière orientation calculée et la prochaine orientation à calculer (avec le suffixe MyComment pour s’y retrouver). La fonction SetOriVar considèra systématiquement que la dernière orientation calculée est celle de la forme Ori-OriXXX avec XXX l’entier le plus élevé.
Les différents outils proposés dans le script sont :
  • le filtrage des points homologues avec HomolFilterMasq sur la base d’un masque 3D saisi avec SaisieMasqQt, pour supprimer éléments mobiles (végétation, vagues, piétons, voitures, etc). Ce processus est abordé dans le détail ci-dessous.
  • l’affinage du modèle de représentation de l’objectif, en passant de RadialBasic à RadialStd, ou RadialExtended
  • l’appel répété à Tapas pour affiner l’orientation. Ce processus nous a été utile dans un cas où une photo qui présentait un faible recouvrement avec les autres photos était mal positionnée. L’appel répété à Tapas a permis de ramener petit à petit la photo à sa vraie position.
  • le calibrage image par image, par exemple en cas d’autofocus activé. Ce processus est abordé dans le détail ci-dessous.

4.5  Phase 4 – Calcul des cartes de profondeur, puis du nuage de points

Vue d’ensemble de la phase 4   Les options principales à renseigner pour cette phase sont :
  • le nom des images maitresses sur la ligne commençant par set MASTER_LIST=...
  • le zoom final sur la ligne set /A "ZOOMF=4"
  • éventuellement le nom de l’orientation utilisée si ce n’est pas celle par défaut (dernier dossier de la forme Ori-OriXXX pour ce script)
  • le dessin des masques des images principales (à l’aide de l’outil SaisieQT décrit ci-dessous)
SaisieQT est l’outil interactif fourni avec MicMac qui permet de dessiner les masques pour chacune des images maitresses. Il sera automatiquement appelé pour chaque image maitresse pour laquelle le script ne trouve pas de masque existant dans le répertoire des images. Pour mémoire les masques 2D sont des fichiers images en noir et blanc au format tif. Ils permettent de ne conserver que les zones intéressantes (en blanc dans le masque) sur les images maîtresses. SaisieMasqQT créé automatiquement le masque tif et son fichier xml associé. Il est possible également d’utiliser le logiciel de dessin GIMP pour retoucher manuellement le masque (voir tutoriel de 2013).
AperoChImSecMM cherche le meilleur groupe d’images secondaires à utiliser avec chaque image maitresse, et créé un fichier ImSec-XXXX.xml dans le répertoire de l’orientation (avec XXXX le nom de chaque image) donnant les résultats des différents groupes d’images secondaires étudiés par le programme.
Les figures exemples dans la suite correspondent à l’image maitresse et au masque de la Fig. 1. Malt calcule pour chaque image maitresse la carte de profondeur correspondante, en prenant en entrée, outre l’image maitresse, l’orientation, les images secondaires et le masque. Ce processus est le plus long en temps de calcul. Il est divisée en plusieurs étapes qui correspondent la plupart du temps à un niveau de zoom chacune (64, 32, 16, 8, jusqu’à ZoomF). Le texte BEGIN ETAPE, , Num=5, DeZoomTer=4, DeZoomIm=4 qui apparaît sur la console indique que l’étape en cours est l’étape 5, avec le zoom 4. Ce message peut apparaître plusieurs fois si Malt traite l’image maîtresse par bloc (Fig. 2). Les résultats temporaires et finaux de Malt seront compris dans le répertoire MM-Malt-Img-XXXX, avec XXXX le nom de chaque image maitresse. Les images de corrélation (Correl_STD-MALT_Num_X.tif avec X le numéro de l’étape) sont créées au début du traitement d’une image maitresse par Malt et sont donc présentes mais complètement noires au début du calcul. Le visionage de ces images avec le logiciel Irfanview (pour ne pas bloquer cette image en écriture) permet de voir la progression du processus et de vérifier visuellement que tout se passe bien (Fig. 3).
  Image maitresse utilisée pour Malt (MicMac)
Fig 1: Image maitresse et masque utilisé pour cet exemple
Image de correlation en cours de traitement par blocs par Malt
Fig 2: Image de correlation en cours de traitement par blocs
Les images de corrélation indiquent le niveau de correlation en chaque pixel de l’image maitresse : en blanc les pixels où la correlation est très bonne, en gris lorsque la correlation se dégrade, et en noir les pixels où la correlation est inexistante. Comme la corrélation sera faible au niveau des sauts de niveaux, les images de correlation des lignes grises (pour les zooms faible du type 64 32 16) puis noires (pour les zooms importants du type 2 1) apparaissent le long du contours des objects. Sur les images de correlation de la Fig. 3, données pour les zooms 32 16 8 et 4, les sauts de niveaux sont visibles le long des nervures de la voûte. On note pour le zoom le plus grand que la correlation est meilleure sur les faux-joints du voutain (corrélation en gris clair), que sur l’enduit lui-même qui forme une surface presque unie (corrélation en gris foncé).
Images de corrélation des zooms 32 16 8 et 4 produites par Malt
Fig 3: Images de corrélation des zooms 32 16 8 et 4
Le résultat de cette phase est le nuage de points global __MMLastNuage.ply qui fusionne l’ensemble des nuages de points de chaque image maitresse. Les nuages de points des images maitresses correspondant à des zooms inférieurs au zoom final, et les cartes de profondeur de ces zooms sont également générés par le script (Fig. 4). Ces cartes de profondeur sont produites par GrShade au format tif, puis compressées (sans perte de qualité à priori) au format png avec ImageMagick dont l’outil convert est fourni avec MicMac, pour économiser l’espace disque occupés par les résultats.
Cartes de profondeur créées avec l'outil GrShade de MicMac
Fig 4: Cartes de profondeur des zooms 32 16 8 et 4
Nuage de point d'une voûte créé avec MicMac
Fig 5: Nuage de point pour le dernier zoom
Affichage du nuage avec Meshlab
Options possible pour Malt et AperoChImSecMM   Si le nuage obtenu est très mauvais, ou très parcellaire, peut-être que Malt n’utilise que 2 images (1 maitresse et 1 secondaire). Il existe plusieurs solutions : regarder manuellement les solutions dans le fichier ImSec-XXXX.xml dans le répertoire d’orientation pour supprimer les groupes d’images qui n’ont pas suffisemment d’images secondaires. Ou bien diminuer le facteur de pénalité PenPerIm (par défaut 0.3) de la commande AperoChImSecMM qui choisi les solutions optimales (nous utilisons PenPerIm=0.05 dans le script. Ou bien augmenter le facteur NbVI de Malt (3 par défaut dans la configuration choisie pour ce tutoriel) qui indique le nombre minimal d’image visibles (NbVI ne semble pas fonctionner dans la version testée).
Les options de Malt par défaut pour le calcul de la carte de profondeur dans le mode GeomImage (qui nous intéresse) sont SzW=1 Regul=0.02. Il est possible de prendre les options SzW=2 Regul=0.05 qui correspondent aux valeurs par dégaut dans le mode Orto des orthophotos pour régulariser un peu le nuage de points (l’option SzW correspond à la taille de la fenêtre de correlation).
Il doit être possible de reprendre les calculs de Malt des cartes de profondeur depuis une étape précédente déjà calculée en utilisant les options Etape0= et Purge=false, mais nous n’avons pas réussi à le faire et cette option ne figure donc pas dans le script proposé ici.
Dans le cas où la scène a beaucoup de relief, (par exemple avec photos d’une vallée de montagne prises depuis le sol), utiliser le réglage par défaut pour l’angle optimal entre images (TetaOpt=0.17 radians, soit environ 10 degrés) fait perdre certaines photos qui sont jugées trop proches du point de vue angulaire par AperoChImSecMM. Alors que seules les photos prises avec des angles proches montrent les mêmes détails des creux du relief. Utiliser le paramètre TetaOpt=0.10 permet d’avoir une couverture plus importante lors de la reconstruction, au détriment de la précision des points obtenus.
En cas d’utilisation de photos au format jpeg, il est inutile d’aller jusqu’à zoomF=1 pour améliorer la précision, parce que la compression des fichiers (subsampling) créé du bruit sur les points qui seront créés. Dans ce cas particulier, le nuage de point obtenu avec ZoomF=2 sera moins dense, mais également moins bruité que le nuage avec ZoomF=1.

5  Améliorations et variantes

Le script de base fonctionnera pour des projets de petite taille (5 à 20 photos) dont les photos sont bien adaptés à la photogrammétrie. Les lignes qui suivent indiquent comment modifier certaines parties du script pour les adapter à des projets plus complexes.
Le défi principal pour l’utilisateur final de MicMac réside la plupart du temps dans le calcul d’une orientation et d’une calibration correcte des images. L’essentiel des lignes qui vont suivrent concerneront donc le calcul de l’orientation et la calibration.

5.1  Options pour la recherche des points clés – Tapioca

On peut remplacer l’étape de base du script pour Tapioca (recherche des points clés) avec une des solutions suivantes, suivant le nombre et la façon dont ont été faites les photos.
::ou bien : comparer directement toutes les photos (plus long)
if %DoPhase1%==true "%BIN_DIR%/mm3d" Tapioca All "%P_ALL%" 800
::ou bien : comparer les photos prises suivant une structure linéaire
if %DoPhase1%==true "%BIN_DIR%/mm3d" Tapioca Line "%P_ALL%" 800 5
::ou bien : comparer les photos par groupes, avec un groupe A faisant le lien avec les autres groupes. Gain de temps lié à la non comparaison des groupes B C D E... entre eux
if %DoPhase1%==true (
"%BIN_DIR%/mm3d" Tapioca MulScale "%P_A%" 300 800
"%BIN_DIR%/mm3d" Tapioca MulScale "%P_B%" 300 800
"%BIN_DIR%/mm3d" Tapioca MulScale "%P_C%" 300 800
"%BIN_DIR%/mm3d" Tapioca MulScale "%P_A%" 300 800 Pat2="%P_B%"
"%BIN_DIR%/mm3d" Tapioca MulScale "%P_A%" 300 800 Pat2="%P_C%"
)
Concernant l’utilisation de l’option Pat2 et son intérêt, voir le sujet du forum MicMac Help to add images incrementally to existing sparse cloud. Sur notre version testée de windows, Tapioca avec l’option Pat2 fonctionnait avec l’option All, mais pas avec l’option MulScale.

5.2  Filtrage des points homologues – Tapas et HomolFilterMasq

Le programme HomolFilterMasq permet de filtrer les points homologues, et de ne conserver que les points homologues contenus à l’intérieur d’un certain volume. Ce volume est défini avec un système de masques avec SaisieMasqQt sur la base du nuage de points grossier créé avec Apericloud. Lors de création du masque 3D avec SaisieMasqQt, les raccourcis claviers importants sont :
  • F9 : bascule entre mode rotation et mode dessin polygone
  • SHIFT et + : faire pour augmenter la taille des points (fonctionne uniquement en mode dessin polygone, une fois que le premier point d’un polygone est dessiné)
  • ESPACE pour ajouter les points d’un polygone, qui deviennent alors plus clairs
  • D pour supprimer les points d’un polygone, qui deviennent alors plus sombres (le raccourci SUPPR indiqué sur l’interface de SaisieMasqQt fait planter le programme sur notre version)
L’utilité de ce filtrage dans le cadre du calcul de l’orientation est de supprimer les points clés des objets mobiles (végétation, reflets des vitres et de l’eau, écume des vagues, piétons, voitures, etc).
Ce type de masque 3D est également utilisé pour C3DC pour limiter le calcul du nuage dense à l’objet étudié (lui aussi contenu à l’intérieur du volume défini grace à SaisieMasqQt). L’objectif de ces deux types de masque n’étant pas le même, on ne masquera donc pas les mêmes choses. Pour HomolFilterMasq, il faut garder tous les détails même ceux qui ne font pas partie de l’objet à modéliser (objets en arrière plans) du moment que ceux-ci sont fixes. Dans le cas d’une maison entourée d’un jardin et de maisons voisines, on masquera donc arbres et herbes (susceptible de bouger légèrement) et on conservera les maisons voisines (qui ajoutent de la profondeur à la scène et améliorent les chances de réussir à obtenir une bonne orientation).
Le résultat de HomolFilterMasq est un nouveau dossier HomolMasqFiltered qui contient le nouvel ensemble de correspondances proposé. Il faut alors utiliser l’option SH=MasqFiltered pour les programmes qui utiliseront les points homologues (Tapas, Campari, Apericloud, etc.). Il est également possible de remplacer le dossier Homol par le dossier HomolMasqFiltered avec les commandes suivantes :
move /Y "%WORKING_DIR%/Homol" "%WORKING_DIR%/Homol_init"
move /Y "%WORKING_DIR%/HomolMasqFiltered" "%WORKING_DIR%/Homol"

5.3  Calibration image par image – Campari

Utilité de Campari   Si l’autofocus était enclenché lors de la prise des photos ou si les informations exif de l’appareil n’étaient pas connues et qu’une longueur focale arbitraire a été appliquée aux données exif pour permettre de trouver une première orientation approximative (photos non destinées à faire de la photogrammétrie initiallement), il est nécessaire de calculer la calibration image par image. C’est un des rôles de Campari. Le résultat de la calibration, au lieu d’être contenue dans les fichiers du type AutoCal_Foc-5200_Cam-Canon_PowerShot_S110.xml sera stockée dans les fichiers qui contiennent déjà habituellement l’orientation de chaque image Orientation-XXXX.xml.
Prenons le cas d’un jeu de photos prises avec un seul objectif (par exemple avec un appareil photo compact dont on n’a pas utilisé le zoom), et avec l’autofocus activé. Il faut alors commencer par trouver une calibration approximative de l’objectif et une orientation approximative des images avec Tapas, et ensuite affiner les deux avec Campari. Tapas et Campari sont en fait deux interfaces qui permettent de rentrer les paramètres adéquats au programme Apero.
Campari s’utilise dans cette situation avec l’option CPI1=1, et les autres paramètres du modèle d’objectif à améliorer :
  • FocFree=1 libère seulement la longueur focale. A noter, le focus (et donc l’autofocus) a une influence sur la longueur focale de l’objectif. Même si les données exif des photos indiquent toutes une focale de 5.2mm par exemple, avec l’autofocus les longueurs focales qui seront trouvées par MicMac seront distribuées autour de cette valeur.
  • PPFree=1 libère seulement le principal point (intersection de l’axe de l’objectif avec le capteur). Si on utilise un modèle RadialBasic ou RadialStd la position du distortion center qui est la même que celle du principal point sera modifiée, mais pas les radial distortion coefficients. Il semble que le principal point sera constant pour un objectif, sauf si la stabilisation d’image est enclenchée sur l’appareil (dans ce cas le principal point change à chaque prise de vue), et peut-être également en cas d’arrêt de l’appareil entre différentes prises de vues.
  • DRMax=n avec n entier libère seulement n radial distortion coefficients (à priori 2 degrés à libérer pour RadialBasic, 3 ou 4 pour RadialStd, et 5 pour RadialExtended)
  • PoseFigee=1 gèle l’orientation des photos
  • AllFree=1 libère l’ensemble des paramètres existant dans le fichier initialement dans le fichier de calibration du répertoire d’orientation (donc l’ensemble des paramètres du modèle d’objectif choisi). Attention AllFree=1 peut libérer plus de degré de liberté pour la distortion que ceux initialement déclaré dans le modèle avec Tapas, ce qui peut engendrer la divergence. Il est donc préférable d’utiliser les autres options ci-dessus si des problèmes de convergence surviennent.
  • les decentric et affine parameters (option AffineFree) ne sont à priori pas utilisé pour les modèles avec radial distortion (RadialBasic etc.). Non utilisé dans ce tutoriel.
Si Campari est utilisé de façon répétitive pour améliorer une orientation, il faut utiliser l’option CPI1=1 lors du premier appel à Campari, et CPI2=1 pour tout appel ultérieur (sinon Campari ne sait pas ou trouver la calibration initiale des photos puisque les fichiers AutoCal_Foc-5200_Cam-Canon_PowerShot_S110.xml ne sont plus créés, la calibration étant stoquée dans les fichiers d’orientation des images.)
Exemples   Quelques exemples d’utilisation de la fonction :
mm3d Campari "%P_All%" Ori001 Ori002 CPI1=1 PoseFigee=1 ne libère aucun paramètre des modèles de focales (défaut pour Campari) et l’orientation des photos est figée. L’orientation trouvée Ori002 sera donc (presque) identique à celle de départ Ori001. Cependant, faire ce calcul peut-être utile, car il fourni le résidu moyen de Campari, qui est différent de celui donné par Tapas. En moyenne sur les exemples que nous avons traité Campari donne un résidu moyen valant 88 à 92% de celui de Tapas. Il ne s’agit pas nécessairement d’une amélioration du calibrage ou de l’orientation mais probablement d’une définition différente des résidus. Nous reviendrons sur le calcul des résidus ci-dessous.
mm3d Campari "%P_All%" Ori001 Ori002 CPI1=1 AllFree=1 libère tous les paramètres des objectifs de toutes les photos, et c’est notre but dans le cas où l’autofocus était activé lors des prises de vue. Si il y a divergence, il peut être utile au lieu de tout libérer de libérer progressivement la distortion avec FocFree=1 PPFree=1 DRMax=0 puis FocFree=1 PPFree=1 DRMax=2.
Calcul du résidu   Les explications qui vont suivre sont approximatives, mais elles devraient néanmoins permettre de cerner la logique qui se cache derrières les résidus utilisés par Tapas et Campari, et de permettre d’utiliser les deux options proposées par Campari pour maitriser le calcul du résidu : SigmaTieP et FactElimTieP.
Le calcul de l’orientation et de la calibration est basée sur la minimisation d’un résidu défini pour chaque image. Cette minimisation de l’ensemble des résidus est appelée compensation. Le résidu d’une image est la moyenne de l’écart en pixel des points homologues par rapport à la position théorique qu’ils devraient occuper dans l’orientation et la calibration en cours. Plus le résidu est faible (à paramètres fixés), plus l’orientation et la calibration de l’image est bonne. En théorie si tous les points clés étaient parfaitement placés (résolution infinie des images et détermination parfaite des points clés), et si le modèle des focales représentant exactement les focales réelles, et si encore d’autres conditions étaient remplies, alors tous les écarts de chaque image tendraient rapidement vers zéro lors de la minimisation (et atteindraient cette valeur).
La réalité est toute autre :
  • la situation théorique n’est jamais atteinte en pratique : certains points clés ont été accouplés alors qu’ils ne représentent pas la même chose (fausses correspondances, appelées outliers), les photos ont nécessairement une résolution finie, les modèles de focales sont par définition des simplifications des objets réels. Pour toutes ces raisons, les écarts ne tendent pas exactement vers zéro.
  • la minimisation est lente, et ne permet pas de rejeter les fausses correspondances
MicMac modifie donc la fonction d’optimisation (la définition du résidu moyen) pour accélérer sa convergence et la précision de l’orientation et calibration obtenues :
  • à chaque étape, les correspondances entre points clés qui dépassent un certain écart sont rejetés (fausses correspondances, outliers). Cet écart est appelé EcartMax dans le programme Apero, qui se cache derrière Tapas et Campari ;
  • une fonction pénalisatrice (comprise entre 0 et 1) est appliquée à tous les écarts, de manière à donner plus d’importance lors de la minimisation aux faibles écarts (qui correspondent probablement à de bonnes correspondances) et à donner moins d’importances aux grands écarts (qui correspondent peut-être à de mauvaises correspondances). Cette fonction pénalisatrice est définie à l’aide du paramètre SigmaPond sous la forme donnée ci-dessous (equation 1). Le détail de la courbe est donnée dans la documentation de MicMac. Plus SigmaPond est faible et plus les mauvais écarts seront pénalisés, et donc les bons écarts (les bons points homologues) favorisés. Avec Tapas, SigmaPond vaut 5 pour les premières étapes et diminue progressivement jusqu’à 2 pour la dernière étape. Avec Campari, SigmaPond vaut 1 pour l’unique étape réalisée (qui démarre au moment où Tapas a déjà fait calculé une première orientation).
\begin{equation} f(x) = \frac{1}{\sqrt{1+\left(\frac{x}{\sigma}\right)^2}} \quad \text{avec $x$ l’écart et $\sigma$=SigmaPond}\label{eq:fpenal} \end{equation}
Prendre SigmaPond et EcartMax le plus faible possible n’est pas possible au début des calculs d’orientation, car on ne sait pas encore à ce moment là qui sont les bonnes et les mauvaises correspondances. Il y aurait donc un risque important de divergence. Pour éviter cette divergence, Tapas appelle plusieurs fois Apero en abaissant progressivement3 SigmaPond de 5 à 2 et EcartMax de 100 à 5. La valeur de EcartMax pour l’étape finale peut être controlée avec l’option EcMax. De son côté Campari appelle une seule fois Apero avec SigmaPond=1 et EcartMax=5. Ces valeurs peuvent être modifiées avec les options SigmaTieP et FactElimTieP, sachant que SigmaPond=SigmaTieP et que EcartMax=SigmaTieP*FactElimTieP.
En conclusion, on peut comparer la qualité de deux orientations via leur résidu moyen seulement si ces derniers ont été calculés avec des paramètres SigmaPond et EcartMax identiques4. Ainsi, pour pouvoir comparer les orientations données par Tapas avec celles de Campari, il faut utiliser Campari avec l’option SigmaTieP=2 FactElimTieP=2.5 (pour la version rev6706).
Jouer sur les paramètres SigmaPond et EcartMax (via SigmaTiePF et FactElimTieP=EcartMax/SigmaPond avec Campari) pourrait permettre de trouver de meilleures calibrations et orientations, mais il y a un risque de divergence d’Apero a trop diminuer SigmaPond et EcartMax.
Les détails sur le résidu sont donnés dans la documentation MicMac de janvier 2016 dans la partie Running the Compensation.

5.4  Tapas – Intégration progressive des images

Dans le cas où le projet comporte un nombre important de photos, essayer de calibrer et d’orienter l’ensemble des photos en une seule étape échoue avec la divergence de Tapas. Une solution est de contrôler soi-même progressivement l’ajout des images, par exemple en orientant les photos d’une façade 1 (photos P_A ici), puis en ajoutant les photos de transition entre la façade 1 et la façade 2 (photos P_B ici), puis en ajoutant les photos de la façade 2 (P_C ici).
Les lignes de la phase 3 sont alors remplacées par les lignes suivantes :
if %DoPhase3%==true (
call:SetOriVar "A" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Tapas RadialBasic "%P_A%" Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_A%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
@echo ""
call:SetOriVar "AB" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Tapas AutoCal "(%P_A%|%P_B%)" FrozenPoses="%P_A%" FrozenCalibs="%P_A%" InCal=!OriIn! InOri=!OriIn! Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "(%P_A%|%P_B%)" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
@echo ""
call:SetOriVar "ABC" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Tapas AutoCal "(%P_A%|%P_B%|%P_C%)" FrozenPoses="(%P_A%|%P_B%)" FrozenCalibs="(%P_A%|%P_B%)" InCal=!OriIn! InOri=!OriIn! Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "(%P_A%|%P_B%|%P_C%)" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
@echo "Etc..."
)
On calcule ici des orientations de plus en plus complètes (Ori001A, Ori002AB, Ori003ABC…). Il faut vérifier à chaque étape que l’orientation obtenue pour les images est correcte (faible résidu moyen, haut pourcentage des points homologues utilisés, vérif visuelle avec Apericloud). Si oui, on peut poursuivre avec l’étape suivante. Ici, on diminue le risque de divergence et on accèlère les calculs en indiquant à Tapas de ne pas essayer d’améliorer le calibrage et le positionnement des photos déjà orientées (options FrozenCalibs et FrozenPoses).
Il faut faire attention à la création des fichiers AutoCal_Foc-XXXX_Cam-Canon_PowerShot_S110.xml dans le cas où les photos correspondent à plusieurs objectifs. En effet, étant donné que seule la première recherche d’orientation qui déclare le modèle d’objectif (ici RadialBasic) créé ces fichiers, si une image des groupes B C D etc. utilise un objectif YYYY qui n’était utilisée par aucune photo du groupe A, le fichier AutoCal_Foc-YYYY_Cam-Canon_PowerShot_S110.xml ne sera pas créé et manquera pour les étapes suivantes. Si ce problème se pose, il faut faire un Tapas RadialBasic avec toutes les images, tout en désactivant la minimisation (option DoC=0 signifiant do compensation) pour créer l’ensemble des fichiers du type AutoCal_Foc-XXXX_Cam-Canon_PowerShot_S110.xml. Puis écraser ces fichiers avec les fichiers de la première orientation. Dans ce cas il faudra commencer par initialiser tous les objectifs:
mm3d Tapas RadialBasic %P_All% Out=Ori-00 DoC=0
et ensuite construire à chaque étape un répertoire d’orientation contenant l’ensemble des fichiers de calibration des objectifs mis à jour. Par exemple après le calcul de l’orientation Ori01, il faudra créer un nouveau répertoire avec les fichiers d’orientation Ori01MAJ comprenant tous les fichiers de calibration des objectifs :
mkdir "%WORKING_DIR%/Ori-01MAJ"
cd "%WORKING_DIR%/Ori-00"
copy /Y "*AutoCal*.*" "%WORKING_DIR%/Ori-01MAJ"
copy /Y "*Orientation*.*" "%WORKING_DIR%/Ori-01MAJ"
cd "%WORKING_DIR%/Ori-01"
copy /Y * "%WORKING_DIR%/Ori-01MAJ"
copy /Y * "%WORKING_DIR%/Ori-01MAJ"
cd "%WORKING_DIR%"

5.5  Tapas – Gestion de la divergence

Pour mémoire, Tapas avec l’option AutoCal charge le modèle de objectif (RadialBasic dans nos exemples) et ses paramètres descriptifs dans les fichiers AutoCal_Foc-XXXX_Cam-Canon_PowerShot_S110.xml, puis cherche à trouver de meilleurs valeurs lors du processus de calibratione et d’orientation, avant d’enregistrer le résultat dans les fichiers AutoCal_Foc-XXXX_Cam-Canon_PowerShot_S110.xml. A contrario Tapas avec l’option Figee recherche uniquement l’orientation relative des photos sans modifier la calibration donnée en entrée.
Si le problème est « mal posé », par exemple dans le cas de photos avec faibles recouvrement, ou de photos avec de multiples objectifs, Tapas diverge souvent (le résidu de certaines photos devient infini).
Sans garantie de réussite, et de manière très sommaire, nous avons noté que les astuces suivantes aidaient parfois à faire converger Tapas :
  • il semble utile de favoriser d’abord la recherche d’une orientation approximative mais cohérente pour l’ensemble des photos avant d’affiner la calibration des objectifs. On peut donc initialiser une calibration sommaire avec quelques photos, puis orienter l’ensemble des photos en utilisant l’option Figee, et une fois l’orientation pour l’ensemble des photos trouvées libérer à nouveau la recherche d’une meilleure calibration avec l’option AutoCal (attention il semble plus prudent d’utiliser l’option Figee combinée avec la libération des paramètres Figee LibFoc=1 LibPP=1 LibCP=1 DegRadMax=2 plutôt que directement l’option AutoCal si on veut limiter effectivement DegRadMax=2)
  • trouver une première solution qui converge en se concentrant sur la focale sans gérer les problèmes de distortion radiale, et introduire la distortion radiale dans un second temps :
    • pour Tapas utiliser les options suivantes : Figee LibFoc=1 LibPP=0 LibCP=0 DegRadMax=0 ou Figee LibFoc=1 LibPP=1 LibCP=0 DegRadMax=0 (les options LibDec=0 LibAff=0 ne sont à priori pas utiles dans le cas d’un modèle type Radial...), et ensuite rechercher d’une meilleure calibration avec l’option Figee LibFoc=1 LibPP=1 LibCP=1 DegRadMax=2. Remarque : Attention AutoCal semble avoir la priorité sur les options du type LibFoc LibPP LibCP DegRadMax. Ainsi AutoCal DegRadMax=0 introduira 5 coefficients de distortions dans le fichier AutoCal_Foc-XXXX_Cam-Canon_PowerShot_S110.xml, alors que Figee DegRadMax=0 n’en introduira aucun. Il vaut mieux donc utiliser l’option Figee plutôt que AutoCal si on veut retarder la prise en compte de la distortion en cas de problèmes de divergence
    • pour Campari utiliser les options suivantes : FocFree=0 PPFree=0 DRMax=0 et libérer progressivement ces paramètres. A noter il n’existe pas apparemment d’option du type CPFree=0. Ne pas utiliser FreeAll=1 qui libère tous les degrés de distortion du modèle RadialExtended, qu’on ne pourra ensuite plus bloquer lors de AperiCloud
  • figer temporairement l’orientation quand on travaille sur la calibration :
    • pour Tapas utiliser FrozenPoses en donnant le nom de toutes les images
    • pour Campari utiliser PoseFigee=1
  • regarder la dernière ligne du type LIB Focale, LIB PP, LIB DR1 qui est apparue avant début de la divergence, ce qui donnera une indication sur un paramètre à bloquer en attendant d’arriver à mieux régler les autres.
Il est à noter que ces astuces sont en fait déjà appliquées par Tapas (initialisation calibration à partir des données exif, puis recherche orientation, puis libération progressive des paramètres de l’objectif). Il s’agit essentiellement ici de ralentir encore plus le processus pour éviter la divergence.

5.6  Verification des recouvrements des images et réduction des points homologues – Schnaps

L’outil Schnaps n’est pas documenté à notre connaissance. Il semble que cet outil découpe chaque image en un certain nombre de fenêtre (1000 par défaut), puis vérifie la présence des points homologues et de leur correspondance avec au moins une autre photo dans chacune de ces fenêtres. Les points homologues surnuméraires dans les fenêtres sont probablement supprimés de manière à produire une répartition plus uniforme des correspondances et ainsi favoriser la convergence lors de la recherche des calibrations et orientations.
"%BIN_DIR%/mm3d" Schnaps "%P_ALL%" NbWin=1000 VeryStrict=0
set SH=SH="_mini"
pause "Voir resultats de Schnaps ci-dessus"
Le résultat de Schnaps est un nouveau dossier Homol_mini qui contient le nouvel ensemble de correspondances proposé. Il faut alors utiliser l’option SH=_mini pour les programmes qui utiliseront les points homologues (Tapas, Campari, etc.). Il est également possible de remplacer le dossier Homol par le dossier Homol_mini avec les commandes suivantes :
move "%WORKING_DIR%/Homol" "Homol_init"
move "%WORKING_DIR%/Homol_mini" "Homol"
Schnaps donne également d’autres informations qui permettent de trier les images :
  • le recouvrement des images (en terme de correspondances) est donnée sur la console lors de l’éxecution
  • le fichier Schnaps_poubelle.txt donne les images qui ont un recouvrement inférieur à 30%.
  • le message Picture AAAAA.JPG : Found 4 pacs indique probablement que l’image AAAA.jpg est en correspondance avec 4 autres images. Si ce nombre vaut 0 ou 1, la correspondance est trop faible et il est préférable de rejeter l’image AAAA.JPG
Sous windows, Schnaps semble planter lorsque les images ont été redécoupés (par exemple dans le cas de photos dont ont ne connait pas l’origine).
Sur les exemples que nous avons utilisé, Schnaps n’a généralement pas permis d’obtenir un meilleur résultat (c’est-à-dire une orientation avec un résidu moyen inférieur à celui avant application de Schnaps aux correspondances). Nous n’avons peut-être pas utilisé Schnaps de façon convenable ou dans des situations appropriées.

5.7  Génération nuage de point automatisé – C3DC

C3DC est un outil qui se substitue à Malt qui donne le nuage de point complet de l’objet, connaissant uniquement l’orientation des images, après avoir entré un masque 3D qui indique la zone à reconstruire (ou à ne pas reconstruire). Il n’est pas utile d’indiquer les images maitresses ni de rentrer les masques 2D image par image, C3DC s’occupe de tout.
call:SetOriVar & REM SetOriVar charge les valeurs de la variable !OriIn!
"%BIN_DIR%/mm3d" SaisieMasqQt "%RESULT_DIR%/ApCl_!OriIn!.ply"
"%BIN_DIR%/mm3d" C3DC QuickMac "%P_ALL%" Ori-!OriIn! Masq3D="%RESULT_SUBDIR%/ApCl_!OriIn!_polyg3d.xml" Out="%RESULT_DIR%/C3DC_Quickmac.ply"
Les options Quickmac, Micmac, Bigmac correspondent respectivement à des zooms finaux de 8 4 et 2 (source forum micmac). L’option Statue est également disponible, et moins rapide que Quickmac.
Pour utilisation de SaisirMasqQt voir les indications ci-dessus.

6  Conclusion

Les lignes qui précèdent n’ont pas été rédigés par un professionnel de la photogrammétrie, et contiennent nécessairement des raccourcis, imprécisions, et erreurs. Nous espérons néanmoins que ce script vous sera utile pour exploiter les grandes possibilités offertes par MicMac.
Les ressources concernant MicMac et disponibles sur internet sont consultables sur les sites suivants :
  • la documentation officielle disponible sur la page de téléchargement de l’IGN
  • Tapenade, un site du laboratoire MAP-Gamsau du CNRS et de l’IGN, avec le détail des protocoles à suivre pour des prises de vues réussiées pour la photogrammétrie (en français).
  • Le forum Micmac, principalement en anglais, avec quelques messages en français.
Nota : L’objectif de ce tutoriel sur MicMac est de partager un script pouvant être utilisé par les utilisateurs amateurs de MicMac sous windows, et d’aider à la diffusion de ce logiciel libre et open-source. La société Bestrema qui héberge cette page n’a pas d’affiliation avec l’IGN (qui est à l’origine du logiciel).
@echo Script pour utilisation de MicMac sous windows
@echo v0.022 - 07/09/2016
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Choix des paramètres"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
:: Répertoires des programmes :
set "BIN_DIR=C:/MicMac64bits6706/bin" &                    REM Executables MicMac
set "BINAUX_DIR=C:/MicMac64bits6706/binaire-aux/windows" & REM Executables programmes auxilliaires MicMac=
set "MESHLAB=C:/Program Files/VCG/MeshLab/meshlab.exe" &  REM Executables Meshlab (visualisation nuages de points)
:: Répertoires du projet
set "WORKING_DIR=C:/micmac_data/zTry3" &                   REM Répertoire de travail où se trouvent les photos
set "MMIMG_SUBDIR=MM-Malt-Img-" &                          REM Préfixe des répertoire temporaires de traitement chaque image maitresse
set "RESULT_SUBDIR=_Result" &                              REM Répertoire où seront enregistrés les résultats finaux (nuages de points, cartes de profondeurs)
:: Noms des images pour la création du nuage de point, utilisant une expression régulière
set "P_A=A_DSC[0-9]{5}.JPG"
set "P_B=B_DSC[0-9]{5}.JPG"
set "P_C=C_DSC[0-9]{5}.JPG"
set "P_ALL=._DSC[0-9]{5}.JPG"
:: Autres - ne pas modifier
set "SH=SH=""" &                                           REM Suffixe par défaut pour Tapas, Campari, Apericloud etc.
set "MMIMG_DIR=%WORKING_DIR%/%MMIMG_SUBDIR%"
set "RESULT_DIR=%WORKING_DIR%/%RESULT_SUBDIR%"
mkdir "%RESULT_DIR%"
cd %WORKING_DIR%
setlocal ENABLEDELAYEDEXPANSION
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Choix des phases à activer
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Phase 1 - recherche des points clés et des correspondances (Tapioca)"
      set DoPhase1=false
@echo "Phase 2 - Calibration intrinsèque et Orientation relative des images (Tapas)"
      set DoPhase3=false
@echo "Phase 3 - Affinage de l'orientation relative des images (optionnel - Tapas, Campari)"
      set DoPhase4Mask=false
      set DoPhase4NewModel=false
      set DoPhase4Multiple=false
      set DoPhase4PerIm=false
@echo "Phase 4 - Calcul de la carte de profondeur, puis du nuage de points (Malt)"
      @echo "toujours fait si on n'arrete pas le script avant lors d'une pause"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Phase 1 - recherche des points clés et des correspondances"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
if %DoPhase1%==true "%BIN_DIR%/mm3d" Tapioca MulScale "%P_ALL%" 300 800
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Phase 2 - Calibration intrinsèque et Orientation relative des images"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
if %DoPhase3%==true (
call:SetOriVar "RadialBasic" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Tapas RadialBasic "%P_ALL%" Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
)
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Phase 3 - Affinage de l'orientation relative des images (optionnel)"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "masque 3D pour supprimer éléments mobiles (végétation, vagues, piétons et voitures) avant affinage orientation"
@echo "-------------------------"
if %DoPhase4Mask%==true (
call:SetOriVar "HomolFilterMasq" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
@echo "saisie masque 3D
if not exist "%RESULT_DIR%/ApCl_!OriIn!.ply" "%BIN_DIR%/mm3d" AperiCloud "!P_All!" !OriIn! Out="%RESULT_SUBDIR%/ApCl_!OriIn!.ply" !SH!
"%BIN_DIR%/mm3d" SaisieMasqQt "%RESULT_DIR%/ApCl_!OriIn!.ply"
@echo ""
@echo "suppression du dossier HomolMasqFiltered qui pourrait pre-exister par securite"
rmdir /S /Q "%WORKING_DIR%/HomolMasqFiltered/"
@echo "filtrage des points homologues sur la base du masque 3D"
"%BIN_DIR%/mm3d" HomolFilterMasq "%P_ALL%" OriMasq3D=!OriIn!/ Masq3D="%RESULT_SUBDIR%/ApCl_!OriIn!.ply"
set "SH=SH="MasqFiltered""
@echo ""
@echo "affinage orientation après filtrage ci-dessus"
"%BIN_DIR%/mm3d" Tapas AutoCal "%P_ALL%" InCal=!OriIn! InOri=!OriIn! Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
)
@echo "activate HomolMasqFiltered if it was calculated in a previous execution of the script"
if exist "%WORKING_DIR%/HomolMasqFiltered/" set "SH=SH="MasqFiltered""
@echo "affinage orientation en passant de RadialBasic à RadialStd, ou RadialExtended"
@echo "-------------------------"
if %DoPhase4NewModel%==true (
call:SetOriVar "RadialStd" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Tapas RadialStd "%P_ALL%" InCal=!OriIn! InOri=!OriIn! Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
)
@echo "Affinage orientation en plusieurs passes, si une photo est mal positionnée"
@echo "-------------------------"
if %DoPhase4Multiple%==true (
call:SetOriVar "IterIn" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
@echo "Create new Ori folder to avoid crushing previous Ori"
mkdir "%WORKING_DIR%/Ori-!OriOut!"
cd "%WORKING_DIR%/Ori-!OriIn!"
copy /Y * "%WORKING_DIR%/Ori-!OriOut!"
cd "%WORKING_DIR%"
call:SetOriVar "IterOut" & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
@echo !OriIn! !OriOut! 
"%BIN_DIR%/mm3d" Tapas AutoCal "%P_ALL%" InCal=!OriIn! InOri=!OriIn! Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
for /L %%I in (1,1,4) do (
"%BIN_DIR%/mm3d" Tapas AutoCal "%P_ALL%" InCal=!OriIn! InOri=!OriIn! Out=!OriOut! SauvAutom=NONE !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" !SH!
cd "%WORKING_DIR%/Ori-!OriOut!""
copy /Y * "%WORKING_DIR%/Ori-!OriIn!"
cd "%WORKING_DIR%"
)
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
)
@echo "Calibrage image par image, par exemple en cas d'autofocus activé"
@echo "-------------------------"
if %DoPhase4PerIm%==true (
@echo "Campari avec SigmaTieP=2 FactElimTieP=2.5 pour obtenir residu comparable a Tapas"
call:SetOriVar PerIm-Sig2 & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Campari "%P_ALL%" !OriIn! !OriOut! CPI1=1 FocFree=1 PPFree=1 DRMax=2 SigmaTieP=2 FactElimTieP=2.5 !SH!
@echo 
@echo "Deuxieme appel avec valeur par defaut SigmaTieP=1 FactElimTieP=5"
call:SetOriVar PerIm-Sig1 & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Campari "%P_ALL%" !OriIn! !OriOut! CPI2=1 FocFree=1 PPFree=1 DRMax=2 !SH!
@echo 
@echo "Troisieme appel avec valeur en renforcant interet pour bons points homologues"
call:SetOriVar PerIm-SigDemi & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
"%BIN_DIR%/mm3d" Campari "%P_ALL%" !OriIn! !OriOut! CPI2=1 FocFree=1 PPFree=1 DRMax=2 SigmaTieP=0.5 FactElimTieP=2 !SH!
"%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" !OriOut! Out="%RESULT_SUBDIR%/ApCl_!OriOut!.ply" CalPerIm=1 !SH!
if exist "%RESULT_DIR%/ApCl_!OriOut!.ply" if exist "%MESHLAB%" ("%MESHLAB%" "%RESULT_DIR%/ApCl_!OriOut!.ply")
pause "Verifier que l'orientation !OriOut! est correcte, avec ApCl_!OriOut!.ply"
)
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Phase 4 - Calcul de la carte de profondeur, puis du nuage de points"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo ""
@echo "Options"
@echo "-------------------------"
set MASTER_LIST=(DSC01409.JPG DSC01416.JPG DSC01418.JPG DSC01425.JPG DSC01426.JPG DSC01429.JPG)
set /A "ZOOMF=4"
@echo "Get last orientation name"
call:SetOriVar & REM SetOriVar charge les valeurs des variables !OriIn! et !OriOut!
set OriF=!OriIn!
@echo ""
@echo "Nettoyage fichiers temporaires et anciens résultats"
@echo "-------------------------"
@echo "pour s'assurer que si des modifications sont faites aux masques, elles seront prises en compte par Malt"
mkdir "%WORKING_DIR%/Tmp-MM-Dir" & cd "%WORKING_DIR%/Tmp-MM-Dir" & del "*Masq*.tif"
mkdir "%WORKING_DIR%/Pyram"      & cd "%WORKING_DIR%/Pyram"      & del "*Masq*.tif"
mkdir "%RESULT_DIR%"             & cd "%RESULT_DIR%"             & del "__MMLastNuage.ply"
cd "%WORKING_DIR%"               & REM mkdir "%WORKING_DIR%/Zooms"
@echo ""
@echo "Options"
@echo "-------------------------"
for %%I in %MASTER_LIST% do (
if not exist "%%~nI_Masq.TIF" ("%BIN_DIR%/mm3d" SaisieMasqQt %%I )
if not exist "Ori-%OriF%/ImSec-%%I.xml" ("%BIN_DIR%/mm3d" AperoChImSecMM "%P_ALL%" %OriF% PenPerIm=0.07)
)
if not exist "%RESULT_SUBDIR%/__MMLastNuage_PosCam.ply" ("%BIN_DIR%/mm3d" AperiCloud "%P_ALL%" %OriF% Out="%RESULT_SUBDIR%/__MMLastNuage_PosCam.ply" WithPoints=0)
@echo ""
@echo "Calculs"
@echo "-------------------------"
for %%I in %MASTER_LIST% do (
	@echo "Calcul de la carte de profondeur avec Malt"
	@echo "--------"
  "%BIN_DIR%/mm3d" Malt GeomImage "%%I" %OriF% Master=AUTO DirMEC="%MMIMG_SUBDIR%%%~nI" Purge=true UseTA=true ZoomI=64 ZoomF=%ZOOMF% AffineLast=true SzW=2 Regul=0.05 NbVI=3
	@echo ""
	@echo "Construction nuages de points ply finaux"
	@echo "--------"
	"%BIN_DIR%/mm3d" Nuage2Ply "%MMIMG_DIR%%%~nI/MMLastNuage.xml" Attr="%%I" RatioAttrCarte=%ZOOMF%
	move /Y "%MMIMG_DIR%%%~nI\MMLastNuage.ply" "%RESULT_DIR%\_%%~nI_MMLastNuage.ply"
	@echo ""
	@echo "Construction nuages de points et cartes de profondeur des étapes intermédiaires"
	@echo "--------"
  cd %MMIMG_DIR%%%~nI
	for /f %%G IN ('dir /b "Z_Num*_DeZoom*_STD-MALT.tif"') DO (
    cd %WORKING_DIR%
	  set "_nom=%%~nG"      & set "_num=!_nom:~5,2!"  & set "_zoom=!_nom:~13,3!"  & REM extract substrings
	  set "_num=!_num:_=!"  & set "_zoom=!_zoom:_=!"  & set "_zoom=!_zoom:m=!"    & set "_zoom=!_zoom:S=!"    & REM delete characters _ m S
		@echo "Decomposition du nom de fichier !_nom!    _num:!_num!    _zoom:!_zoom!"
		@echo ""
		@echo "Construction nuages de points ply"
		if !_num! GEQ 4 (
		  "%BIN_DIR%/mm3d" Nuage2Ply "%MMIMG_DIR%%%~nI/NuageImProf_STD-MALT_Etape_!_num!.xml" Attr="%%I" RatioAttrCarte=!_zoom!
		  move /Y "%MMIMG_DIR%%%~nI\NuageImProf_STD-MALT_Etape_!_num!.ply" "%RESULT_DIR%\_%%~nI_NuageImProf_Etape!_num!_Zoom!_zoom!.ply"
		)
		@echo ""
		@echo "Construction cartes de profondeur avec ombrage"
    if !_num! GEQ 3 (
		  "%BIN_DIR%/mm3d" GrShade "%MMIMG_DIR%%%~nI/Z_Num!_num!_DeZoom!_zoom!_STD-MALT.tif" Out="%RESULT_DIR%/_%%~nI_GrShade_Etape!_num!_Zoom!_zoom!.tif" Mask="%MMIMG_DIR%%%~nI/Masq_STD-MALT_DeZoom!_zoom!.tif" NbDir=20
		)
	)
  cd %WORKING_DIR%
)
@echo ""
@echo "Compression des cartes de profondeur avec ombrage (tif -> png)"
@echo "-------------------------"
cd %RESULT_DIR%
FOR /f %%G IN ('dir /b "*.tif"') DO (
"%BINAUX_DIR%/convert" "%RESULT_DIR%/%%~nG.tif" -quality 95 "%RESULT_DIR%/%%~nG.png"
del "%%~nG.tif"
)
cd %WORKING_DIR%
@echo ""
@echo "Fusion des nuages de points ply des différentes images maitresses"
@echo "-------------------------"
"%BIN_DIR%/mm3d" MergePly "%RESULT_DIR%\.*_MMLastNuage.*.ply" Out="%RESULT_DIR%/__MMLastNuage.ply"
:: Pour voir les éventuels messages d'erreur avant disparition de la fenêtre commande :
pause
:: ne pas mettre exit ici, il faut que dos puisse avoir accès aux fonctions ci-dessous
:: see http://www.dostips.com/DtTutoFunctions.php for the definition of dos functions
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
@echo "Definition of functions - script will automatically close after functions are read"
@echo "---------------------------------------------------"
@echo "---------------------------------------------------"
:SetOriVar
@echo off
SETLOCAL
set /A "OriNum=0"
for /F %%G in ('dir /B "Ori-Ori0*"') do (
set /A "OriNum+=1" & set "OriName=%%G"
)
set /A "OriNum+=1"
if %OriNum% LEQ 9 (set "OriNum=0%OriNum%")
(ENDLOCAL & REM -- RETURN VALUES
    set OriIn=%OriName:~4,66%
		set OriOut=Ori0%OriNum%%~1
)
@echo on
GOTO:EOF
:GetImMinMax
@echo off
set /A "LocalNum=0"
for /F %%G in ('dir /B "*.JPG"') do (
set /A "LocalNum+=1"
if !LocalNum! == %~1 (set ImMin=%%G)
if !LocalNum! == %~2 (set ImMax=%%G)
)
set %LocalInter%=[%ImMin%,%ImMax%]
@echo on
GOTO:EOF
:GetImListe
SETLOCAL
@echo off
set "LocalInter="
set /A "LocalNum=0"
for /F %%G in ('dir /B "*.JPG"') do (
set /A "LocalNum+=1"
if !LocalNum! GEQ %~1 (
if !LocalNum! LEQ %~2 (
set LocalInter=!LocalInter!%%G,
) ) )
set "LocalInter=%LocalInter%,"
set "LocalInter=%LocalInter:,,=%"
set "LocalInter=^(%LocalInter:,=^|%^)"
(ENDLOCAL & REM -- RETURN VALUES
    set %~3=%LocalInter%
)
@echo on
GOTO:EOF
:: Pour voir les éventuels messages d'erreur avant disparition de la fenêtre commande :
pause & exit
 
Article mis en ligne le : 07/09/2016.

Notes

1 Friedt 2014 « Reconstruction de structures tridimensionnelles par photographies : le logiciel MicMac » – accessible sur http://jmfriedt.free.fr/
2 Nous ne nous hasarderons pas à tenter de donner une définition d’orientation réussie ici, tout dépend du degré de qualité souhaité et de la qualité des photos disponibles.
3 Pour comparer les appels de Tapas et de Campari à Apero, comparer les fichiers Apero-Glob-New.xml et Apero-Compense.xml dans le répertoire include/XML_MicMac de Micmac
4 Autre exemple : recalculer une orientation obtenue avec Campari standard en utilisant Campari et en bloquant le calibrage et l’orientation, et avec l’option SigmaPond=SigmaTiePF=0.5 donnera un résidu moyen moins important qu’avec la valeur par défaut, alors que les orientations et calibration de départ et d’arrivée sont quasiment identiques.