Tutoriel 2: lancer vos traitements en batch
Transcription
Tutoriel 2: lancer vos traitements en batch
Tutoriel 2: lancer vos traitements en batch Si vous avez besoin de réaliser une série de traitements, sans interaction utilisateur, sur une série d’images, la programmation batch est particulièrement adaptée. Vous devez pour cela restaurer ENVI en mode batch (aucune interface ENVI n’apparaîtra), afin d’avoir accès à toutes les routines ENVI. Utilisez maintenant ENVI comme une simple librairie de traitements ! Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Les grandes étapes d’un traitement batch . . . 2 FID, DIMS et POS . . . . . . . . . . . . . . . . . . . . . . . . 3 Exemple 1: appliquer un filtre à une série d’images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Exemple 2: rajouter de nouveaux traitements et créer un fichier log . . . . . . . . . . . . . . . . . . . . . . 5 1 2 Tutoriel 2: lancer vos traitements en batch Introduction Pour débuter, nous allons reprendre un exemple simple du tutoriel 1: l’application d’un filtre de détection de contours, SOBEL, à une série d’image situées dans un répertoire. Les images filtrées ainsi créées seront sauvegardées dans un répertoire de sortie. Ensuite, ce tutoriel vous montrera comment simplement rajouter de nouveaux traitements comme la réalisation d’une classification non supervisées, l’application d’un filtrage majoritaire, etc. Nous allons écrire les différents codes de nos traitements batch dans une session IDL simple (elle se reconnait au prompt IDL>). Les grandes étapes d’un traitement batch Le schéma ci-dessous montre les principales instructions pour créer une routine de traitement simple en mode batch : Figure 2-1. Instructions principales pour créer un traitement batch ENVI, RESTORE_BASE_SAVE_FILES Restaurer ENVI en mode ENVI_BATCH_INIT batch Ouverture de l’image à traiter (non-interactif) ENVI_OPEN_FILE, filename, R_FID=fid IF (fid EQ -1) THEN BEGIN ENVI_BATCH_EXIT RETURN ENDIF (ENVI_OPEN_DATA_FILE pour un format externe) Récupération d’infos sur l’image ENVI_FILE_QUERY, fid, NS=ns, NL=nl, NB=nb, ...$ Application d’un traitement et sauvegarde de l’image produite ENVI_DOIT, ’..’, FID=fid,DIMS=dims,POS=pos,$ R_FID=r_fid, OUT_NAME=... (ou toute autre routine de traitement ENVI) Fermeture du mode batch ENVI ENVI_BATCH_EXIT Tutoriel 2: lancer vos traitements en batch 3 FID, DIMS et POS Dès que vous commencerez à écrire vos propres routines de traitements avec la librairie ENVI, vous constaterez que trois variables reviennent sytématiquement: FID (File Identifier) Il s’agit d’un entier long. Les entrées/Sorties dans ENVI ne fonctionnent pas de la même manière que dans IDL. IDL utilise des LUN (Logical Unit Number) et ENVI des FID (File ID). Dans IDL, l'utilisateur doit gérer les E/S en obtenant une unité logique (à l'ouverture du fichier) et ensuite en utilisant des routines du type READ/WRITE. Dans ENVI, toutes les E/S sont contrôlées en interne . L'utilisateur ne va pas utiliser des routines telles que OPENR, OPENW, etc. mais plutôt des routines de lecture spécifiques d'ENVI et qui retourneront un identifiant sur le fichier. Cet identifiant de fichier devra par contre être communiqué à chacune des routines de traitement. Avec cette méthode, l'utilisateur peut ouvrir autant de fichiers qu'il le souhaite. Les FIDs peuvent être de trois types: FID: un FID correspondant à une image d’entrée. R_FID (Returned FID) : si la routine de traitement aboutit à la création d'une nouvelle image, un FID est retourné. M_FID (Mask FID) : permet de spécifier le fichier à utiliser comme masque. Un FID, R_FID ou M_FID est stocké sous forme d’un entier long. DIMS: sous-échantillage spatial La variable DIMS définit un sous-ensemble spatial à utiliser par la routine (utiliser ce mot-clef même si toute l'image est à traiter). Table 2-1. Signification des 5 valeurs de DIMS index exemple signification 0 -1L Pointeur sur une région d’intérêt qui définirait un sousensemble spatial. Si aucune, indiquer -1. 1 0 Colonne de départ (en index de position) 2 ns-1 Colonne de fin (en index de position) 3 0 Ligne de départ (en index de position) 4 nl-1 Ligne de départ (en index de position) La variable DIMS est codée sous la forme d’un tableau de 5 entiers longs. 4 Tutoriel 2: lancer vos traitements en batch POS: sous-échantillonage spectral La variable POS définit un sous-ensemble spectral. Cela consiste à indiquer les index des bandes sur lesquelles effectuer le traitement (il s’agit d’index de position). La variable POS est codée sous la forme d’un tableau de N entiers longs, N ne pouvant pas dépasser le nombre de bandes du fichier. Exemple 1: appliquer un filtre à une série d’images La technique utilisée pour appliquer le filtre de SOBEL sur chaque image, est d’utiliser la routine ENVI équivalente à l’outil Band Math interactif: ENVI_DOIT, ’MATH_DOIT’ en spécifiant ’SOBEL(b1)’ comme expression (mot-clef EXP). Pour simplifier l’exercice, nous appliquerons le filtre que sur la première bande du fichier. Ils existent d’autres solutions pour effectuer ce traitement, mais nous ne les verrons pas dans ce tutoriel. batch_processes1 (batch_processes1.pro) PRO batch_processes1, inputRep, outputRep COMPILE_OPT idl2 ;; Test repertoire de sortie (contiendra les images traitees) stack = SCOPE_TRACEBACK(/STRUCTURE) sourceDir = FILE_DIRNAME((stack[N_ELEMENTS(stack)-1]).filename,$ /MARK_DIRECTORY) IF N_ELEMENTS(outputRep) EQ 0 || ~FILE_TEST(outputRep) $ THEN outputRep = sourceDir ;; Test repertoire d’entree (contient les images a traiter) default = FILEPATH('', ROOT_DIR=!DIR, $ SUBDIRECTORY=['products','envi42','data']) IF N_ELEMENTS(inputRep) EQ 0 || ~FILE_TEST(inputRep) $ THEN inputRep = default ;; Restaurer ENVI en mode batch ENVI, /RESTORE_BASE_SAVE_FILES ENVI_BATCH_INIT ;; Rechercher tous les fichiers ENVI situes ;; dans le repertoire d'entree imgFilepath = FILE_SEARCH(inputRep, '*.img', COUNT=nbFiles) FOR i=0, nbFiles-1 DO BEGIN ;; Lire l'image et recuperer le FID ENVI_OPEN_FILE, imgFilepath[i], R_FID=fid IF (fid EQ -1) THEN BEGIN Tutoriel 2: lancer vos traitements en batch 5 CONTINUE ;on passe au fichier suivant ENDIF ;; Infos sur le fichier ENVI_FILE_QUERY, fid, DIMS=dims, NL=nl, NS=ns, NB=nb ;; Appliquer un filtre de SOBEL sur la 1ere bande ;; Sauvegarder l'image filtree ENVI_DOIT, 'MATH_DOIT', EXP='SOBEL(b1)', $ FID=[fid], DIMS=dims, POS=[0], $ OUT_NAME=outputRep+$ FILE_BASENAME(imgFilepath[i], '.img')+ '_sobel.img' ENDFOR ;; Fermer le mode batch ENVI_BATCH_EXIT END Exemple 2: rajouter de nouveaux traitements et créer un fichier log Création d’un fichier log Pour créer un fichier log (pour contenir les éventuelles erreurs survenues au cours du traitement batch et/ou pour simplement retracer l’avancement des traitements), il suffit de rajouter, au niveau de la procédure BATCH_INIT, les mots-clefs suivants: [...] ENVI, /RESTORE_BASE_SAVE_FILES ENVI_BATCH_INIT, $ BATCH_LUN=batch_unit,$ LOG_FILE=sourceDir+'batch_log.txt' [...] BATCH_LUN correspond au numéro d’unité logique IDL de notre ficher log. Ce numéro est nécessaire pour pouvoir écrire dans le fichier. Par exemple, si aucune image n’existe dans notre répertoire d’entrée, on écrira: [...] imgFilepath = FILE_SEARCH(inputRep, '*.img', COUNT=nbFiles) IF nbFiles EQ 0 THEN BEGIN PRINTF, batch_unit, ’No files to process in this directory’ PRINTF, batch_unit, SYSTIME() ENVI_BATCH_EXIT RETURN ENDIF [...] 6 Tutoriel 2: lancer vos traitements en batch De même si une erreur survient à l’ouverture de l’image d’entrée, il est nécessaire de l’indiquer dans le fichier log: [...] ENVI_OPEN_FILE, imgFilepath[i], R_FID=fid IF (fid EQ -1) THEN BEGIN PRINTF, batch_unit, ’Could not open file ’+imgFilepath[i] CONTINUE ENDIF [...] Enfin, nous pouvons indiquer à la fin du programme que le traitement batch est terminé: [...] PRINTF, batch_unit, 'Batch process ended at '+SYSTIME() ENVI_BATCH_EXIT END Ajout de nouveaux traitements Nous allons montrer dans cette section combien il est facile d’adapter notre routine pour effectuer de nouveaux traitements. Nous allons remplacer l’instruction chargée d’appliquer un filtre de SOBEL, par l’enchainement d’une classification et d’un posttraitement: un filtrage majoritaire chargé d’éliminer les classes trop petites. Pour ce faire, nous allons utiliser les routines suivantes: ENVI_DOIT, ’CLASS_DOIT’ et ENVI_DOIT, `CLASS_MAJORITY_DOIT': [...] ENVI_DOIT, 'MATH_DOIT', EXP='SOBEL(b1)', $ FID=[fid], DIMS=dims, POS=[0], $ OUT_NAME=outputRep+$ FILE_BASENAME(imgFilepath[i], '.img') + '_sobel.img' ;; Classification non supervisee K-Means class_names = ['unclass', 'cl1', 'cl2', 'cl3', 'cl4', 'cl5'] lookup = [[0,0,0],$ [255,0,0],[0,255,0],[0,0,255],[255,255,0],[0,255,255]] ENVI_DOIT, 'CLASS_DOIT', FID=fid, DIMS=dims, POS=LINDGEN(nb), $ CLASS_NAMES=class_names, LOOKUP=lookup, METHOD=7,IN_MEMORY=0,$ ITERATION=1, CHANGE_THRESH=0.5, NUM_CLASSES=5, $ R_FID=r_fid, OUT_NAME=outputRep+$ FILE_BASENAME(imgFilepath[i], '.img') + '_kmean.img' ;; Filtrage majoritaire ENVI_FILE_QUERY,r_fid, NS=ns,NL=nl,NB=nb,NUM_CLASSES=num_classes,$ ENVI_DOIT, 'CLASS_MAJORITY_DOIT', $ FID=r_fid, POS=[0], DIMS=[-1L, 0, ns-1, 0, nl-1], $ METHOD=0, KERNEL_SIZE=[5,5], $ OUT_NAME=outputRep+$ FILE_BASENAME(imgFilepath[i], '.img') + '_maj.img', $ CLASS_PTR=LONARR(num_classes)+1 [...] Tutoriel 2: lancer vos traitements en batch Ci-dessous, figure le code complet de ce deuxième exemple: batch_processes2 (batch_processes2.pro) PRO batch_processes2, inputRep, outputRep COMPILE_OPT idl2 ;; Test repertoire de sortie (contiendra les images traitees) stack = SCOPE_TRACEBACK(/STRUCTURE) sourceDir = FILE_DIRNAME((stack[N_ELEMENTS(stack)-1]).filename,$ /MARK_DIRECTORY) IF N_ELEMENTS(outputRep) EQ 0 || ~FILE_TEST(outputRep) $ THEN outputRep = sourceDir ;; Test repertoire de’entree (contient les images a traiter) default = FILEPATH('', ROOT_DIR=!DIR,$ SUBDIRECTORY=['products','envi42','data']) IF N_ELEMENTS(inputRep) EQ 0 || ~FILE_TEST(inputRep) $ THEN inputRep = default ;; Restaurer ENVI en mode batch ENVI, /RESTORE_BASE_SAVE_FILES ENVI_BATCH_INIT, BATCH_LUN=batch_unit,$ LOG_FILE=sourceDir+'batch_log.txt' ;; Rechercher tous les fichiers ENVI situes ;; dans le repertoire d'entree imgFilepath = FILE_SEARCH(inputRep, '*.img', COUNT=nbFiles) IF nbFiles EQ 0 THEN BEGIN PRINTF, batch_unit, 'No files to process in this directory' PRINTF, batch_unit, SYSTIME() ENVI_BATCH_EXIT RETURN ENDIF FOR i=0, nbFiles-1 DO BEGIN ;; Lire l'image et recuperer le FID ENVI_OPEN_FILE, imgFilepath[i], R_FID=fid IF (fid EQ -1) THEN BEGIN PRINTF, batch_unit, 'Could not open file '+imgFilepath[i] CONTINUE ENDIF ;; Infos sur le fichier ENVI_FILE_QUERY, fid, DIMS=dims, NL=nl, NS=ns, NB=nb ;; Appliquer un filtre de SOBEL sur la 1ere bande ;; Sauvegarder l'image filtree ;ENVI_DOIT, 'MATH_DOIT', EXP='SOBEL(b1)', FID=[fid],$ ;DIMS=dims, POS=[0], OUT_NAME=outputRep+$ 7 8 Tutoriel 2: lancer vos traitements en batch ;FILE_BASENAME(imgFilepath[i], '.img') + '_sobel.img' ;; Rajouter une classification non supervisee class_names = ['unclass', 'cl1', 'cl2', 'cl3', 'cl4', 'cl5'] lookup = [[0,0,0], $ [255,0,0],[0,255,0],[0,0,255],[255,255,0],[0,255,255]] ENVI_DOIT, 'CLASS_DOIT', FID=fid, DIMS=dims, POS=LINDGEN(nb), $ CLASS_NAMES=class_names, LOOKUP=lookup, METHOD=7, $ IN_MEMORY=0, ITERATION=1, CHANGE_THRESH=0.5,NUM_CLASSES=5,$ R_FID=r_fid, OUT_NAME=outputRep+$ FILE_BASENAME(imgFilepath[i], '.img') + '_kmean.img' ENVI_FILE_QUERY, r_fid, $ NS=ns, NL=nl, NB=nb, NUM_CLASSES=num_classes ENVI_DOIT, 'CLASS_MAJORITY_DOIT', $ FID=r_fid, POS= [0], DIMS=[-1L, 0, ns-1, 0, nl-1], $ METHOD=0, KERNEL_SIZE=[5,5], $ OUT_NAME=outputRep+$ FILE_BASENAME(imgFilepath[i], '.img') + '_maj.img', $ CLASS_PTR=LONARR(num_classes)+1 ENDFOR ;; Indiquer dans notre fichier log que le traitement ;; batch est termine PRINTF, batch_unit, 'Batch process ended at '+SYSTIME() ;; Fermer le mode batch ENVI_BATCH_EXIT END