Ca avance bien 👍
Co-authored-by: Laureηt <laurent@fainsin.bzh> Co-authored-by: pejour <pejour@users.noreply.github.com>
This commit is contained in:
parent
5cbb0d31ac
commit
4384319a03
297
docs/slides.md
297
docs/slides.md
|
@ -20,81 +20,116 @@ title: Bureau d'étude de PI3D
|
|||
|
||||
---
|
||||
|
||||
## Exemple Level sets 2D
|
||||
## Plan du BE
|
||||
|
||||
<div class="h-100 flex items-center text-2xl">
|
||||
|
||||
- Définitions
|
||||
- L'idée générale
|
||||
- Hyposthèses
|
||||
- L'algorithme
|
||||
- Résultats
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Notre objectif dans ce BE c'était donc d'implémenter ce procédé.
|
||||
Et pour ce faire on avait besoin de faire les étapes suivantes:
|
||||
|
||||
|
||||
- Définitions
|
||||
1. Level sets
|
||||
2. MVS
|
||||
- L'idée générale
|
||||
- Hyposthèses
|
||||
1. Discrétisation de l'espace
|
||||
2. Binarisation du levelset
|
||||
- L'algorithme
|
||||
1. Initialisation du volume
|
||||
2. Mise à jour du volume
|
||||
- Résultats
|
||||
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Définition
|
||||
### Level sets
|
||||
|
||||
<img src="/figs/lvl7_2D.gif" class="m-auto"/>
|
||||
|
||||
$\mathcal{V} = \{ \textbf{Q} = (X, Y) \in \mathbb{R}^2, u(\textbf{Q}) > s \}, \quad s\in [0,1], \quad u \colon \mathbb{R}^2 \to [0, 1]$
|
||||
|
||||
<img src="/figs/lvl7_2D.gif" class="m-auto mt-5"/>
|
||||
|
||||
<!--
|
||||
level set ≃ un seuillage. \
|
||||
Ici on représente le seuillage d'une fonction par un contour rouge, avec le resultat binarisé à droite.
|
||||
Ça fait un peu penser aux contours actifs, et on peut considérer les levels sets comme une généralisation des contours actifs.
|
||||
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Définition du Level sets (2D)
|
||||
|
||||
<style>
|
||||
span.katex {
|
||||
position: absolute;
|
||||
bottom: 5%;
|
||||
left: 8%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<img src="/figs/wikipedia_top.png" class="m-auto -mt-12"/>
|
||||
<img src="/figs/wikipedia_bottom.png" class="m-auto -mt-12"/>
|
||||
|
||||
$\mathcal{V}_t = \{ \textbf{Q} = (X, Y) \in \mathbb{R}^2, u(\textbf{Q}) > t \}, \quad t\in [0,1], \quad u \colon \mathbb{R}^2 \to [0, 1]$
|
||||
|
||||
<a href="https://en.wikipedia.org/wiki/Level-set_method" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Wikipedia</a>
|
||||
|
||||
<!--
|
||||
Définition mathématique et continue des levels sets:
|
||||
|
||||
Volume = Ensemble des points de l'espace tel que, l'image de ces points par une fonction valide une condition
|
||||
|
||||
- V_t -> volume (2D ici, gris en bas) que l'on souhaite obtenir/approximer
|
||||
- V -> volume (2D ici, noir à droite)
|
||||
- Q -> point 2D de l'espace
|
||||
- u -> fonction indicatrice (que l'on souhaite apprendre) qui indique "l'intériorité" d'un point Q dans V_t
|
||||
- t -> seuil qui détermine la valeur à partir de laquelle on est dans V_t
|
||||
|
||||
Pour un levelset 2D, on peut représenter u en 3D, t par un plan, et notre volume V_t par tout ce qui se situe au dessus du plan t.
|
||||
- u -> fonction indicatrice (que l'on souhaite apprendre) qui indique "l'intériorité" d'un point Q dans V
|
||||
- s -> seuil qui détermine la valeur à partir de laquelle on est dans V
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Exemple Level sets 3D
|
||||
### Exemple Level sets 3D
|
||||
|
||||
<img src="/figs/lvl7_3D.gif" class="m-auto -mt-1 h-125"/>
|
||||
<div class="flex items-center">
|
||||
<img src="/figs/lvl7_3D.gif" class="h-110"/>
|
||||
<figure>
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/MarchingCubes.svg/350px-MarchingCubes.svg.png" class="h-50">
|
||||
<figcaption class="text-center">Marching cubes</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
La définition précédente se généralise très bien aux espace de dimension supérieurs, voici un exemple 3D.
|
||||
Juste on vous parle de la 2D psk c'est plus simple.
|
||||
Par exemple ici on peut pas représenter u, car il nous faudrait une représentation 4D.
|
||||
Par contre on peut vous montrer le résultat de V_t pour différent t.
|
||||
En ce qui concerne le rendu de la surface 3D, on utilise l'ago de marching cubes.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Évolution de $u_t$
|
||||
## Définition
|
||||
### Multi-view Stereo
|
||||
|
||||
<img src="/figs/lvl7_2D_1.png" class="m-auto h-110"/>
|
||||
<img src="https://people.inf.ethz.ch/~moswald/publications/resources/Oswald-DA-2007.png" class="m-auto h-105"/>
|
||||
|
||||
<a href="https://people.inf.ethz.ch/~moswald/publications/resources/Oswald-DA-2007.pdf" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Concurrent Stereo Reconstruction, Martin R. Oswald, 2007</a>
|
||||
|
||||
<!--
|
||||
MVS -> reconstruction 3D à partir des positions des caméras et de leur image.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## L'idée générale
|
||||
### Évolution de $u$
|
||||
|
||||
<img src="/figs/lvl7_2D_1.png" class="m-auto h-100"/>
|
||||
|
||||
<a href="https://hal.inria.fr/inria-00073673/document" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Variational principles, surface evolution, PDEs, level set methods, and the stereo problem - Olivier Faugeras, Renaud Keriven, 1998</a>
|
||||
|
||||
<!--
|
||||
Faugeras et Keriven ont écrit ce "livre" pour poser pleins de preuves mathématiques sur des problèmes variationnels... dont les levels sets.
|
||||
Et donc dans le leur "livre" ils montrent plusieurs exemples de levels sets.
|
||||
Ils montrent un procédé pour mettre à jour u_t (le contour bleu) pour que celui-ci converge vers un volume capturé (le contour rouge) par des caméras (dont les poses sont connues).
|
||||
Ils montrent un procédé pour mettre à jour u (le contour bleu) pour que celui-ci converge vers un volume capturé (le contour rouge) par des caméras (dont les poses sont connues).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Évolution de $u_t$
|
||||
## L'idée générale
|
||||
### Évolution de $u$
|
||||
|
||||
<img src="/figs/lvl7_2D_2.png" class="m-auto h-110"/>
|
||||
<img src="/figs/lvl7_2D_3.png" class="m-auto h-100"/>
|
||||
|
||||
<a href="https://hal.inria.fr/inria-00073673/document" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Variational principles, surface evolution, PDEs, level set methods, and the stereo problem - Olivier Faugeras, Renaud Keriven, 1998</a>
|
||||
|
||||
|
@ -104,35 +139,10 @@ changement de topologie du level set
|
|||
|
||||
---
|
||||
|
||||
## Évolution de $u_t$
|
||||
## Hypothèses
|
||||
### Discrétisation de l'espace
|
||||
|
||||
<img src="/figs/lvl7_2D_3.png" class="m-auto h-110"/>
|
||||
|
||||
<a href="https://hal.inria.fr/inria-00073673/document" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Variational principles, surface evolution, PDEs, level set methods, and the stereo problem - Olivier Faugeras, Renaud Keriven, 1998</a>
|
||||
|
||||
---
|
||||
|
||||
## Plan du BE
|
||||
|
||||
<div class="h-100 flex items-center text-2xl">
|
||||
|
||||
- Discrétisation de l'espace
|
||||
- Initialisation du volume
|
||||
- Mise à jour du volume
|
||||
- Résultats
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Notre objectif dans ce BE c'était donc d'implémenter ce procédé.
|
||||
Et pour ce faire on avait besoin de faire les étapes suivantes:
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Discrétisation de l'espace <br> Simplification du problème
|
||||
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/b/bc/Voxels.svg" class="m-auto mr-50 -mt-13 h-110">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/b/bc/Voxels.svg" class="m-auto mr-50 -mt-13 h-100">
|
||||
|
||||
<style>
|
||||
span.katex {
|
||||
|
@ -141,8 +151,9 @@ span.katex {
|
|||
}
|
||||
</style>
|
||||
|
||||
$\mathbb{R}^3 \to \mathbb{V} \newline \implies \mathcal{V} = \{ \textbf{v} = (x, y, z) \in \mathbb{V}, u(\textbf{v}) > 0 \}, \quad u \colon \mathbb{V} \to \{0, 1\}$
|
||||
### Binarisation du levelset
|
||||
|
||||
$\mathbb{R}^3 \to \mathbb{V} \newline \implies \mathcal{V} = \{ \textbf{v} = (x, y, z) \in \mathbb{V}, u(\textbf{v}) > 0 \}, \quad u \colon \mathbb{V} \to \{0, 1\}$
|
||||
|
||||
<a href="https://en.wikipedia.org/wiki/Voxel" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Wikipedia</a>
|
||||
|
||||
|
@ -155,7 +166,8 @@ Et donc t on va aussi le définir égal à 0.
|
|||
|
||||
---
|
||||
|
||||
## Initialisation du volume
|
||||
## L'algorithme
|
||||
### Initialisation du volume
|
||||
|
||||
- Définition des bornes de notre grille de voxels:
|
||||
- $x \in \llbracket x_{\min}, x_{\max} \rrbracket$
|
||||
|
@ -175,6 +187,57 @@ Comme on l'a vu dans les exemple de Faugeras, il nous faut un u_0 initial (le co
|
|||
|
||||
---
|
||||
|
||||
## L'algorithme
|
||||
### Principe du Shape from Silhouette
|
||||
|
||||
<img src="https://www.researchgate.net/profile/Silvio-Savarese/publication/221625880/figure/fig1/AS:652956261158913@1532688312594/Shape-from-Silhouettes-The-silhouette-and-camera-location-for-each-view-forms-a-cone.png" class="m-auto h-105">
|
||||
|
||||
<a href="https://ieeexplore.ieee.org/document/1024034" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Implementation of a Shadow Carving System for Shape Capture, doi: 10.1109/TDPVT.2002.1024034</a>
|
||||
|
||||
<!--
|
||||
On suppose qu'on connait les poses de plusieurs caméras, ainsi que les masques de l'objet qu'elles capturent.
|
||||
On va prendre tous les voxels de notre grille et les projeter sur chacune de nos caméras.
|
||||
Si on voxel tombe à l'exterieur du masque d'au moins d'une caméra, on le supprime.
|
||||
Il en résulte l'enveloppe convexe de l'objet (nuage de points / voxels).
|
||||
Plus on a de caméra, meilleure sera la définition de l'enveloppe.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
### Shape from Silhouette 3D
|
||||
|
||||
<div class="flex items-center">
|
||||
<img src="/figs/example3D.gif" class="m-auto h-110">
|
||||
<iframe frameborder="0" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true" allow="autoplay; fullscreen; xr-spatial-tracking" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share width="100%" height="100%" src="https://sketchfab.com/models/4da17838dd5f497faa147db5febd21d9/embed"></iframe>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
25 poses, torus avec briques, génération blender, masques parfait par render raytracing (cycles).
|
||||
|
||||
nuage de voxel. si nuage de points -> conversion en mesh possible grace aux marching cubes.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## L'algorithme
|
||||
### Lancer de rayon (Fast Voxel Intersect)
|
||||
|
||||
<div class="grid grid-cols-2 col-auto w-110 m-auto">
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141883810914427/fvi2.png" class="m-auto h-55"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141884242931712/fvi4.png" class="m-auto h-55"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141884679147602/fvi6.png" class="m-auto h-55"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141885056622661/fvi8.png" class="m-auto h-55"/>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
### Shape from Silhouette 2D
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1069974891023056926/image.png" class="m-auto -mt-2 h-110">
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1069974281175449630/image.png" class="m-auto -mt-1 h-11">
|
||||
|
||||
---
|
||||
|
||||
## Mise à jour du volume
|
||||
|
||||
<img src="/figs/update.png" class="m-auto h-120">
|
||||
|
@ -191,79 +254,6 @@ Comme on l'a vu dans les exemple de Faugeras, il nous faut un u_0 initial (le co
|
|||
|
||||
---
|
||||
|
||||
## Principe du Shape from Silhouette
|
||||
|
||||
<img src="https://www.researchgate.net/profile/Silvio-Savarese/publication/221625880/figure/fig1/AS:652956261158913@1532688312594/Shape-from-Silhouettes-The-silhouette-and-camera-location-for-each-view-forms-a-cone.png" class="m-auto mt-2 h-110">
|
||||
|
||||
<a href="https://ieeexplore.ieee.org/document/1024034" class="absolute bottom-0 font-extralight mb-1 mr-2 right-0 text-xs">Implementation of a Shadow Carving System for Shape Capture, doi: 10.1109/TDPVT.2002.1024034</a>
|
||||
|
||||
<!--
|
||||
On suppose qu'on connait les poses de plusieurs caméras, ainsi que les masques de l'objet qu'elles capturent.
|
||||
On va prendre tous les voxels de notre grille et les projeter sur chacune de nos caméras.
|
||||
Si on voxel tombe à l'exterieur du masque d'au moins d'une caméra, on le supprime.
|
||||
Il en résulte l'enveloppe convexe de l'objet (nuage de points / voxels).
|
||||
Plus on a de caméra, meilleure sera la définition de l'enveloppe.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Shape from Silhouette 3D
|
||||
|
||||
<img src="/figs/example3D.gif" class="m-auto mt-2 h-110">
|
||||
|
||||
<!--
|
||||
25 poses, torus avec briques, génération blender, masques parfait par render raytracing (cycles).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Résultat Shape from Silhouette 3D
|
||||
|
||||
<iframe frameborder="0" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true" allow="autoplay; fullscreen; xr-spatial-tracking" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share width="100%" height="100%" src="https://sketchfab.com/models/4da17838dd5f497faa147db5febd21d9/embed"></iframe>
|
||||
|
||||
<!--
|
||||
nuage de voxel. si nuage de points -> conversion en mesh possible grace aux marching cubes.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## Shape from Silhouette 2D
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1069974891023056926/image.png" class="m-auto -mt-2 h-110">
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1069974281175449630/image.png" class="m-auto -mt-1 h-11">
|
||||
|
||||
---
|
||||
|
||||
## Résultat Shape from Silhouette 2D
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1069973956263686164/Screenshot_from_2023-01-31_14-30-53.png" class="m-auto h-110">
|
||||
|
||||
---
|
||||
|
||||
## Lancer <br> de rayon
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141883810914427/fvi2.png" class="m-auto -mt-10 h-125"/>
|
||||
|
||||
---
|
||||
|
||||
## Lancer <br> de rayon
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141884242931712/fvi4.png" class="m-auto -mt-10 h-125"/>
|
||||
|
||||
---
|
||||
|
||||
## Lancer <br> de rayon
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141884679147602/fvi6.png" class="m-auto -mt-10 h-125"/>
|
||||
|
||||
---
|
||||
|
||||
## Lancer <br> de rayon
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1068141885056622661/fvi8.png" class="m-auto -mt-10 h-125"/>
|
||||
|
||||
---
|
||||
|
||||
## Itération du Level Set
|
||||
|
||||
<div class="flex">
|
||||
|
@ -273,9 +263,33 @@ nuage de voxel. si nuage de points -> conversion en mesh possible grace aux marc
|
|||
|
||||
---
|
||||
|
||||
## Résultats (TODO)
|
||||
## Résultats
|
||||
### L'environnement
|
||||
|
||||
<img src="https://media.tenor.com/_NuHtjgRyvcAAAAC/kekw.gif" class="m-auto h-100">
|
||||
<!-- TODO -->
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070291885823889408/peanut.png"/>
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Résultats
|
||||
### Les données
|
||||
|
||||
<!-- TODO: mettre les cams a guache et les mask et imagesa droite les unes sur les autres -->
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070293528288165930/peanut_cams.png"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070292853282054225/Image0000.png"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070292853495975988/Image0010.png"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070292853764407306/Image0020.png"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070292923322744903/Image0000.png"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070292923549224980/Image0010.png"/>
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070292923754741770/Image0020.png"/>
|
||||
|
||||
---
|
||||
|
||||
## Résultats
|
||||
### L'initialisation (Shape from Silhouette)
|
||||
|
||||
<img src="https://cdn.discordapp.com/attachments/953586522572066826/1070287482186383450/init.png" class="m-auto h-120">
|
||||
|
||||
---
|
||||
|
||||
|
@ -286,5 +300,6 @@ nuage de voxel. si nuage de points -> conversion en mesh possible grace aux marc
|
|||
- Réalisation du SfS en 2D/3D
|
||||
- Réalisation du MVS par level sets en 2D avec utilisation du SfS
|
||||
- Résultat en 3D ?
|
||||
- Passer en continu au lieu de binaire
|
||||
|
||||
</div>
|
||||
|
|
|
@ -58,7 +58,8 @@ for i in range(nb_cams):
|
|||
plt.xlim(-7, 7)
|
||||
plt.ylim(-7, 7)
|
||||
plt.axis("equal")
|
||||
plt.savefig("data/peanut/peanut.png", dpi=300,
|
||||
plt.axis("off")
|
||||
plt.savefig("data/peanut/peanut_cams.png", dpi=300,
|
||||
bbox_inches="tight", pad_inches=0, transparent=True)
|
||||
plt.close()
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ Z = Z.T
|
|||
|
||||
plt.figure()
|
||||
plt.axis("equal")
|
||||
plt.axis("off")
|
||||
plot_voxels(Z, "#fff", 1.0, True)
|
||||
plot_voxels(voxel, "#00f", 0.5, False)
|
||||
for i in range(nb_frame):
|
||||
|
@ -233,7 +234,7 @@ for p in range(11):
|
|||
|
||||
occurences = [[x, values.count(x)] for x in set(values)]
|
||||
occurences = sorted(occurences, key=lambda x: x[1], reverse=True)
|
||||
if occurences[0][1] >= len(values) * 0.68:
|
||||
if occurences[0][1] >= len(values) * 0.7:
|
||||
voxel_[i, j] = 1
|
||||
color = "#0f0"
|
||||
else:
|
||||
|
@ -258,13 +259,13 @@ for p in range(11):
|
|||
|
||||
voxel = voxel_
|
||||
|
||||
plt.savefig(f"evol{p}.png", dpi=300, bbox_inches="tight", pad_inches=0, transparent=True)
|
||||
plt.savefig(f"evol{p:02}.png", dpi=300, bbox_inches="tight", pad_inches=0, transparent=True)
|
||||
|
||||
plt.figure()
|
||||
plt.axis("equal")
|
||||
plot_voxels(Z, "#fff", 1.0, True)
|
||||
plot_voxels(voxel, "#00f", 0.5, False)
|
||||
plt.savefig(f"shape{p}.png", dpi=300, bbox_inches="tight", pad_inches=0, transparent=True)
|
||||
plt.savefig(f"shape{p:02}.png", dpi=300, bbox_inches="tight", pad_inches=0, transparent=True)
|
||||
plt.close("all")
|
||||
|
||||
# plt.show()
|
||||
|
|
Loading…
Reference in a new issue