Project

General

Profile

Documentation outils de filtrage/conversion (preprocessing)

Les outils de filtrage constituent un ensemble d'exécutables en ligne de commande qui prend en entrée les fichiers csv capturés par le chariot de mesures et qui produit en sortie un fichier dont le format est conservé mais dont les données sont filtrées.

Tous les outils ont été développés en C++ avec Qt version 5.4 afin de rendre plus aisé le parsage des arguments, la manipulations des chaines de caractères, les conversions, etc. Un des outils qui effectue une approximation de courbes à l'aide de l'algorithme de Douglas Peucker utilise la librairie OpenCV 3.1.0.

Le but de travailler avec des outils en ligne de commande est de pouvoir par la suite automatisé les traitements sur les fichiers lorsqu'un utilisateur upload un fichier. Un script python qui automatise déjà une bonne partie des traitements a déjà été développé afin de gagner du temps lorsque nous effectuons de nouvelles mesures.

Les chapitres ci-dessous décrivent la structure du projet qui englobe tous les outils de filtrage et documente leur utilisation et en particulier, les arguments requis en entrée et les outputs.

Le projet DatasProcessing

Sur le repository Git du projet SPAMOR, le projet N°05 (05_DatasProcessing) contient les sources des outils de filtrage/convertion (pre-processing). Le projet se trouve dans le sous-dossier DatasProcessing/ qui contient les sources de tous les outils ligne de commandes.

Structure du projet

Le projet contient 5 sous-projets dont 4 produisent des exécutables (ayant un main) :

Voici un brève description des différents projets, chaque projet fait l'objet d'un chapitre spécifique ci-dessous.

  • Le projet FilterProfiles : Prend en entrée un fichier de mesures CSV ainsi qu'une taille de fenêtre (pour le filtrage médian) et filtre pour chaque ligne les 810 points du Sick avec un filtre médian de la taille de fenêtre données en argument. Le résultat est stocké dans un nouveau fichier dont la structure est exactement sembable mais les données du Sick sont filtrées.
  • Le projet ApproximateProfiles : Prend en entrée un fichier de mesures CSV, convertis les 810 points du Sick en coordonnées cartésiennes, approxime le profile avec Douglas-Peucker, stocke le profile approximé dans un nouveau fichier contenant les données originale ainsi que (à la fin de chaque ligne) le tag <APPROX> suivi des points cartésiens qui approximent le profil. Le format des points est le suivant: <APPROX>;x1,y1;x2,y2;x3,y3;...
  • Le projet ColumnFilter : Prend en entrée un fichier de mesures CSV ainsi qu'une liste d'indices de colonnes (commençant à 0) et une liste de tailles de fenêtre (pour le filtrage médian) puis filtre chaque colonne donnée par son index avec la taille de fenêtre associée au moyen d'un filtre médian. Le résultat est stockée dans un nouveau fichier conservant la structure originale mais contenant les données filtrées
  • Le projet PointsConverter: Prend en entrées un fichier contenant les courbes approximées (points cartésiens, tag <APPROX>) puis les convertis dans le domains 3D. ATTENTION: cet outil est pour le moment en mode debug et n'est pas entièrement terminé. Le résultat est stocké dans un nouveau fichier ne contenant que les points convertis sous la forme x1,y1,z1;x2,y2,z2;... (une ligne par profil de point converti).
  • Le projet Common : Ne génère pas d'exécutable mais une librairie statique qui contient des outils communs aux 4 autres projets ci-dessus. Ce projet contient notamment les classes de parsing du CSV ainsi que les extracteurs de données, la classe du filtre médian (utilisé dans FilterColumns et FilterProfiles) et d'autres utilitaires communs.

FilterProfiles

Voici l'aide de l'outil (./FilterProfiles --help)

Voici un exemple de commande qui filtre les points du fichier mesures.csv avec une taille de fenêtre de 11 et enregistre le résultat dans le fichier mesures_filtered.csv :

./FilterProfiles -w 11 -o mesures_filtered.csv mesures.csv

Le paramètre -s permet de changer le séparateur csv (pour le parsing) et est facultatif -> défaut ';'.
Le paramètre -o permet de spécifier le chemin du fichier de sortie, si ce paramètre est inexistant alors un fichier [original_filename]_filtered[WINDOWSIZE].csv est créé dans le working directory.
Le paramètre -w permet de spécifier la taille de fenêtre pour le filtrage (valeur entière et impaire) si la valeur n'est pas spécifié la valeur 5 est utilisée par défaut.

On trouve dans le fichier de sortie les mêmes valeurs que dans le fichier d'entrées à l'exceptions des données du Sick (810 points) qui sont filtrées. Le filtre médian ne remplace pas la valeur originale par la valeur filtrée si celle-ci a une valeur de 0.

ApproximateProfiles

Voici l'aide de l'outil (./ApproximateProfiles --help)

Voici un exemple de commande qui approxime les points du fichier mesures.csv avec un treshold de 0.04 (4cm) donné à l'algorithme de Douglas-Peucker et enregistre le résultat dans le fichier mesures_approximate.csv :

./ApproximateProfiles -t 0.04 -o mesures_approximate.csv mesures.csv

Le paramètre -s permet de changer le séparateur csv (pour le parsing) et est facultatif -> défaut ';'.
Le paramètre -o permet de spécifier le chemin du fichier de sortie, si ce paramètre est inexistant alors un fichier [original_filename[THRESHOLDVALUE]]_approximate.csv est créé dans le working directory.

On trouve dans le fichier résultats les même données que dans le fichier d'entrée avec un tag supplémentaire <APPROX> à la fin de chaque ligne et les points du profil approximé en coordonnées cartésiennes.

NOTE IMPORTANT : Pour compiler ce projet requiert la librairie OpenCV 3.1.0. (http://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html#gsc.tab=0), les modules contrib ne sont pas nécessaire. Il faut adatper le fichier ApproximateProfiles.pro selon les spécificité de l'installation d'openCV (chemins vers les headers et les libs so)

ColumnFilter

Voici l'aide de l'outil (./ColumnFilter --help)

Voici un exemple de commande qui filtre le fichier mesures.csv et sauvegarde le résultats dans le fichier mesures_columnfiltered.csv, la commande filtre les colonnes suivantes:
  1. la colonne d'indice 14 (15e colonne) filtrée avec une taille de fenêtre de 11
  2. la fenêtre d'indice 15 (16e colonne) filtrée avec une taille de fenêtre de 13
  3. la fenêtre d'indice 16 (17e colonne) filtrée avec une taille de fenêtre de 21
./ColumnFilter -c 14 -w 11 -c 15 -w 13 -c 16 -w 21 -o mesures_columnfiltered.csv mesures.csv

NOTE IMPORTANTE : Notez que l'ordre des paramètres -c et -w est important ! Le nombre de paramètre -c doit être égal au nombre de paramètre -w.

Le paramètre -s permet de changer le séparateur csv (pour le parsing) et est facultatif -> défaut ';'.
Le paramètre -o permet de spécifier le chemin du fichier de sortie, si ce paramètre est inexistant alors un fichier [original_filename]_medianfiltered_c[COLUMNINDICES]_w[WINDOWSSIZES].csv est créé dans le working directory.

PointsConverter

Voici l'aide de l'outil (./PointsConverter --help)

Voici un exemple de commande qui converti les points approximés du fichier mesures_approximate.csv (sortie de ApproximateProfiles) dans le domaine 3D (à définir si relatif ou absolu WGS84 car encore en état de développement) avec comme arguments les transformations mécaniques relative au chariot (translations, rotations de l'origine du chariot au capteur sick). Le fichier de sortie converted_points.csv contient uniquement les points en 3D (aucune autre donnée) pour le moment (à définir le format final).

./PointsConverter -o converted_points.csv mesures.csv 0 0.7 1.4 0 45 0

Le paramètre -s permet de changer le séparateur csv (pour le parsing) et est facultatif -> défaut ';'.
Le paramètre -o permet de spécifier le chemin du fichier de sortie, si ce paramètre est inexistant alors un fichier [original_filename]_converted_points.csv est créé dans le working directory.

Pour rappel, les dimensiosn et systèmes d'axes du chariot [[https://projets-labinfo.he-arc.ch/attachments/download/2178/ING-DT160504-SPAMOR_Cart_Dimensions_CoordSys.pdf]]

Pour le moment la convertion s'effectue en utilisant le compass du GPS comme direction et la distance parcourue entre deux points du GPS comme translation si > 0 sinon la distance des compteurs.

Sous-projet Common

Le projet common contient les classes qui permettent de parser le csv et d'extraire les données et de les convertir dans le bon type. Il contient également le filtre médian, la classe LFLocation et quelques autres petits utilitaires pour la création de fichiers ou des structures de données (Point, Poit3D).

Les quatre projets ci-dessus dépendent du projet Common. La dépendance est inscrite dans le fichier DatasProcessing.pro comme suit :

...
TEMPLATE = subdirs
SUBDIRS = Common \
    FilterProfiles \
    ApproximateProfiles \
    PointsConverter \
    ColumnFilter

FilterProfiles.depends = Common
ApproximateProfiles.depends = Common
PointsConverter.depends = Common
ColumnFilter.depends = Common
...

FileSpliter

La classe MeasuresFileSplitter du projet Common permet la lecture des fichiers de mesures csv.

Pour utiliser le splitter il faut:
  • Instancier un objet MeasuresFileSplitter
  • Utiliser la méthode setFile(QFile*) pour lui attribuer un fichier à lire (normalement ce fichier à été ouvert et instancier dans le main des exécutables par rapport au chemin donné en argument)
  • La méthode next() permet de sauter à la ligne suivante
  • Les méthodes getXXXLine(); permettent de récupérer une certaines partie de la ligne csv (données GPS, IMU, Sick, Coders, etc.)

Les extracteurs

Pour chaque type de données (GPS, IMU, Coders, Sick) que l'on obtient à l'aide des méthodes getXXXLine() du splitter existe une classe statique XXXExtractor. Les classes extractor permettent d'extraire depuis la ligne csv la valeur parsée dans le bon type.

Voici un snippet d'exemple pour extraire la ligne des données des codeurs et l'avance de chaque roue à l'aide du splitter et de l'extractor associé:

MeasuresFileSplitter *splitter = new MeasuresFileSplitter();
splitter->next();
QString codersLine = splitter->getCodersMeasuresLine();

double rightWheelDist = CodersExtractor::extractRightWheelDistance(codersLine, separator);
double leftWheelDist = CodersExtractor::extractLeftWheelDistance(codersLine, separator);

Il existe 5 extractors:
  • ApproxExtractor pour extraire les points du profil approximé depuis la ligne splitter->getApproxPointsLine();
  • CodersExtractor pour extraire les mesures enregistrées par les codeurs depuis la ligne splitter->getCodersMeasuresLine();
  • GPSExtractor pour extraires les mesures enregistrées par le YoctoGPS depuis la ligne splitter->getGPSMeasuresLine();
  • IMUExtractor pour extraire les mesures enregistrées par le capteur 3D depuis la ligne splitter->getIMUMeasuresLine();
  • SickExtrator pour extraire les 810 valeurs polaires du capteur Sick depuis la ligne splitter->getSickMeasuresLine();

Projet RunProcessing

Sur le repository Git du projet SPAMOR, le projet N°06 (06_RunProcessing) contient le script python qui automatise le lancements des outils.

Ce script effectue les opérations suivantes:

  • Créé un dossier pour stocker les résultats
  • Pour chaque fichier *.csv du dossier d'input
  1. Filtre les données du capteur Sick avec un filtre médian, sauvegarde le résultat intermédiaire dans un sous-dossier du dossier résultats
  2. Approxime les profils avec le threshold donné en paramètre, sauvegarde le résultat intermédiaire dans un sous-dossier du dossier résultats
  3. Filtre les colonnes données en arguments avec les tailles de fenêtres données et stock le résultat dans un sous-dossier du dossier résultats

On peut donc appliquer la pipeline de traitement à tous les fichiers de mesures d'un dossier et récupérer les résultats intermédiaires (après filtrage Sick, après Filtrage + approximation, après Filtrage + approximation + filtrage colonnes). La convertion des points n'est pas encore intégrée au script python.

Le nom du dossier de résultats ressemble à output[INPUTFOLDERPATH]_window[SICKWINDOWSIZE]_threshold[DOUGLASPEUCKERTHRESH] et contient les sous dossiers:
  1. filtered : avec les données du capteur Sick filtrées
  2. approx : avec les profils en cartésien approximés à partir de l'output du point 1
  3. columns_filtered: avec les différentes colonnes filtrées depuis l'output du point 2

Fonctionnement

Le script python s'attend à trouver les exécutables ApproximateProfiles, ColumnFilter et FilterProfile dans le dossier d'exécution. Il faut donc compiler les projets et placer les exécutables dans un dossier avec le script comme suit (Build Release conseillé pour performances):

Voici l'aide de l'utilitaire

Et voici un exemple de son utilisation:

python run_processing.py ~/street_beausite/ 11 0.1 14,15,16,17,18 11,11,11,11,11

La commande ci-dessus applique à tous les fichiers de mesures *.csv du dossier ~/street_beausite/ un filtrage médian de taille 11 sur les données du Sick (output sous-dossier filtered/), puis une approximation de Douglas-Peucker avec un threshold de 0.04 mètres (output sous-dossier approx/) puis applique un filtre médian sur les colonnes d'indice 14, 15, 16,17, 18 toutes avec une taille de fenêtre de 11 (output sous-dossier columns_filtered/).

Une exécution réussie devrait donner un output console de ce genre:

Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/filtered/20160511_beausite_002_filtered11.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/filtered/20160511_beausite_000_filtered11.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/filtered/20160511_beausite_001_filtered11.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/filtered/street_beaustite_000_filtered11.csv" 
Approximation process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/approx/20160511_beausite_001_filtered11_approx0.1.csv" 
Approximation process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/approx/street_beaustite_000_filtered11_approx0.1.csv" 
Approximation process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/approx/20160511_beausite_000_filtered11_approx0.1.csv" 
Approximation process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/approx/20160511_beausite_002_filtered11_approx0.1.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/columns_filtered/20160511_beausite_000_filtered11_approx01_colfilter14-15-16-17-18_11-11-11-11-11.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/columns_filtered/street_beaustite_000_filtered11_approx01_colfilter14-15-16-17-18_11-11-11-11-11.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/columns_filtered/20160511_beausite_001_filtered11_approx01_colfilter14-15-16-17-18_11-11-11-11-11.csv" 
Filtering process successfully completed. Ouptut saved in "/home/brandtk/Qt/runProcessing/output[homebrandtkmeasures]_window11_threshold0.1/columns_filtered/20160511_beausite_002_filtered11_approx01_colfilter14-15-16-17-18_11-11-11-11-11.csv"