GitLab now enforces expiry dates on tokens that originally had no set expiration date. Those tokens were given an expiration date of one year later. Please review your personal access tokens, project access tokens, and group access tokens to ensure you are aware of upcoming expirations. Administrators of GitLab can find more information on how to identify and mitigate interruption in our documentation.
Mon travail pour ce projet d'étude à la recherche s'est découpé en 2 grandes parties. J'ai tout d'abord commencé par faire une étude préliminaire
et un état de l'art sur l'extraction d'arbres à partir de nuages de points.
La seconde partie consiste en l'implémentation d'un algorithme répondant au problème.
Mon travail pour ce projet d'étude à la recherche s'est découpé en 2 grandes parties. J'ai tout d'abord commencé par faire
une étude préliminaire du problème et un état de l'art sur l'extraction d'arbres à partir de nuages de points.
La seconde partie a consisté en l'implémentation d'un algorithme répondant au problème.
\section{Etat de l'art}
La segmentation d'arbres à partir de nuages de points est un domaine déjà bien étudié depuis plusieurs années. Celle-ci se concentre
La segmentation d'arbres à partir de nuages de points est un domaine déjà bien étudié depuis plusieurs années. Celui-ci se concentre
principalement sur l'étude forestière. Généralement, ces études se basent sur des nuages souvent
générés par drones avec système LiDaR embarqué. Le point commun de ces études est de travailler sur
des nuages de points beaucoup plus précis que ceux utilisés pour ce projet. En effet la triangulation de points
à partir d'une vidéo nécéssite que l'objet reste immobile, ce qui n'est pas toujours garanti avec les feuillages
balancés par le vent d'où quelques approximations.
\subsection{Trunc-growth}
\subsection{Croissance à partir du tronc}
Pour extraire la géométrie d'un arbre, plusieurs approches sont envisageables. Une première est d'essayer de déduire quels
points font partie de l'arbre ciblé en se basant sur une croissance de région partant du tronc.
...
...
@@ -223,12 +217,14 @@ TODO :
Ce sont des techniques plutôt précises et fiables, cependant elles se basent sur des données initiales de bonne qualité,
générées par scanner embarqué.
\subsection{Bassin-versants}
\subsection{Bassinversants}
Un second groupe de méthode utilise la propriété des arbres d'être de plus grande hauteur au niveau de la cime.
C'est l'approche employée par Ma et al. \cite{ma_novel_2021} pour segementer les arbres d'une forêt scannée au LiDaR aérien.
C'est l'approche employée par Ma et al. \cite{ma_novel_2021} pour segmenter les arbres d'une forêt scannée au LiDaR aérien.
Les arbres voisins sont ensuite séparés en utilisant un algorithme de "bassin versants" :
la séparation est définie à l'endroit où le gradiant change de direction. Dans notre cas, on a un mauvais visuel
la séparation est définie à l'endroit où le gradiant change de direction.
Dans notre cas, on a un mauvais visuel
de la cime mais elle doit pouvoir être utilisable tout de même. En plus de ça on dispose de beaucoup d'informations
sur le bas de la canopée, ce qui pourrait permettre d'appliquer cet algorithme par le haut et le bas en même temps.
...
...
@@ -238,7 +234,7 @@ TODO :
\subsection{Coupe minimale}
Enfin, un 3e type d'approche ressort de façon récurente pour la séparation entre arbres voisins :
la génération d'une coupe minimale entre les 2 régions concernées par les arbres voisins.
la génération d'une coupe minimale entre les 2 régions concernées par les deux arbres connexes.
Li et al. \cite{li_branch-trunk-constrained_2022}
: optimise par supervoxels =>
...
...
@@ -259,10 +255,10 @@ En vrai on est mieux là déjà
performant et est adapté pour ce genre de traitements. C'est aussi un langage que je maitrise très bien,
de même pour l'équipe d'Icube.
Durant ma phase de recherche, j'ai fait quelques expérimentations en python dans un notebook jupyter, notament pour openCV qui
y est très simple à utiliser avant de les intégrer en dur dans le programme C++
Durant ma phase de recherche, j'ai fait quelques expérimentations en python dans un notebook jupyter, notament
pour utiliser openCV qui y est très facile à utiliser avant de les intégrer en dur dans le programme C++.
Avec le recule je me suis rendu compte que le temps gagné en utilisant le python était tout autant perdu avant le temps d'exécution.
Avec le recule je me suis rendu compte que le temps gagné en utilisant python était autant perdu avec le temps d'exécution.
Avoir une partie python et C++ m'a aussi contraint à implémenter des outils additionnels pour faire les conversions entre
les deux langages et à avoir plein de sous-étapes où je passe de l'un à l'autre dans le procédé,
ce qui s'est avéré être assez fastidieux.
...
...
@@ -276,49 +272,57 @@ En vrai on est mieux là déjà
permettant de visualiser la densité du nuage de point sur une image 2D, d'abord en "vue du dessus", puis en tranches verticales.
J'ai initialement utilisé la librairie PCL (Point Cloud Library) pour le traitement de nuages de points.
J'ai remarqué plus tard que celle-ci était beaucoup trop lourde et complexe pour l'usage fait,
je l'ai ensuite remplacé par une simple classe permettant de faire des opérations
je l'ai donc remplacée par une simple classe permettant de faire des opérations
basiques sur les nuages de points. J'ai utilisé la librairie happly pour charger les fichiers .ply.
L'application est depuis beaucoup plus rapide à compiler et plus simple à maintenir.
J'ai commencé par travailler sur une carte des densité correspondant à la somme des tranches verticales de l'arbre
(issues d'un découpage en parts de gateau)
(issues d'un découpage en parts de gateau) Cette visualisation m'a permis d'envisager différentes
approches intéréssantes dont j'ai discuté avec mes encadrants en réunion. L'approche par coupe minimale
semblait très encourageante.
J'ai ensuite expérimenté différentes méthodes dessus pour la filtrer avec OpenCV. J'ai d'abord tenté
J'ai ensuite expérimenté différentes méthodes sur ces coupes pour la filtrer avec OpenCV. J'ai d'abord tenté
une ouverture morphologique qui a donné de très bon résultats. Les points correspondant au bruit et aux tranches particulières
(creux et fortes excroissances) sont largement retirés et on retrouve l'aspect approximatif de l'arbre.
(trou dans l'arbre, grosses branches, ou connexion avec un arbre voisin)
sont largement retirés et on obtient un profile approximatif de l'arbre dans sa globalité
J'ai aussi essayé de filtrer en fonction du seuil, mais le résultat n'était pas meilleur et
la définition de ce seuil n'est pas triviale à définir.
la définition de ce seuil n'est pas triviale à définir. J'y reviendrai plus bas, mais au final
c'est peu être une approche plus judicieuse dont il faudra débattre dans de futurs travaux.
Enfin j'ai fait quelques tests pour voir s'il n'y avait pas une coupure nette en regardant les histogrammes des cartes de densité,
mais ceux-ci n'ont rien donné.
Enfin j'ai fait quelques tests pour voir s'il n'y avait pas une coupure nette en regardant les histogrammes des cartes de densité
permettant de définir ce seuil, mais je n'ai rien observé de flagrant.
Dans notre cas, la faible précision du nuage de point semblait rendre l'utilisation des approches précédemment employées
beaucoup plus hasardeuse. De plus, l'objectif n'est pas uniquement de segmenter le nuage de point, mais en plus
d'en générer une enveloppe afin de par exemple déterminer le volume du feuillage.
Je n'ai pas à ma disposition de réelles vérités de terrain permettant de determiner précisément l'efficacité de l'algorithme.
Pour finir, je noterai que je n'ai pas à ma disposition de réelles vérités de terrain permettant de determiner quantitativement l'efficacité de l'algorithme.
La qualité de cette enveloppe sera à déterminer par la comparaison visuel du maillage généré à partir du nuage de point.
En étudiant les données, une autre idée est ressortie : étudier le nuage de points par "tranches" en suivant un découpage
en "parts de gâteau". Cette approche m'a semblé relativement simple à implémenter, et aussi très adapté aux jeux de donnée
sur lesquels elle allait être appliquée. En effet, la majorité des points sont concentrés sur l'arbre étudié,
ce qui facilite énormément sa reconnaissance. L'étude préliminaire des cartes de densités générées à partir de ces tranches permet
de plutôt bien visualiser la séparation avec les arbres voisins, ce qui m'avait alors semblé
plutôt encourageant. Une approche par extraction de coupe minimale m'a semblé être le plus approprié.
\subsection{Programme C++}
TODO Parler du programme et faire le lien avec le chapitre ~\ref{chap:approach}
- Documenté
- Code simple
- Code découpé en modules (module Core bien distinct du reste) et multithreadé
- Ensemble d'outils pour la manipulation de nuages de points et de maillage
L'objectif de ce TER est de faire une étude préliminaire du problème et de proposer une ébauche de solution.
mon travail devant être repris par une autre personne, j'ai essayé de le rendre le plus clair possible
et de le segmenter au maximum en sous-modules indépendants. Par exemple, l'algorithme
du procédé complet tient en un fichier qui devrait être assez facile à lire ou à améliorer, et peut être
rapidement intégré à un autre projet.
Avoir un code propre lisible et documenté permet aussi d'y déceller plus facilement les erreurs et les
incohérences. C'est quelque chose qui m'a été très bénéfique au moment de la remise au propre de l'algorithme
où j'ai constaté quelques approximations qui pouvaient être corrigées (comme un décallage de l'angle des tranches)
et aussi quelques erreurs (la tranche globale était utilisée à l'envers)
Tant qu'à faire, et aussi pour rendre le peaufinage des paramètres plus rapide,
j'ai parallélisé au maximum l'algorithme. Par chance un réglage optimal se contente de 25 tranches,
et je dispose de 24 coeurs sur mon CPU (ca tombe bien), j'ai donc simplement assigné un thread par tranche.
Avec ce réglage, on a presque aucun accès concurent et toutes les resources matérielles sont utilisées
ce qui garanti un temps d'éxécution optimal (qui tombe à 2 ou 3 secondes en moyenne)
Lorsque j'ai commencé à pouvoir générer un maillage, j'ai eu beaucoup de difficultés à le placer précisément
en utilisant CloudCompare, que je trouvais par ailleurs très peu pratique à utiliser.
J'ai donc décidé de tout intégrer dans une application 3D développée pour l'occasion. J'ai réutilisé le moteur
de rendu openGL que j'avais mis au point pour un précédent projet, ce qui m'a permi de gagner beaucoup de temps.
Cette application regroupe tous les outils développés pour ce projet
(visualisation des cartes de densité sous plusieurs angles, visualisation du tronc etc...)
et pourra servir de bac-à-sable pour de futures expérimentations. Cette application compile
sur linux et windows et devrait être rapidement utilisable sous macOs.