Projets

Projets

Cinq choses que j'ai construites.

🧰 Travaux choisis · Théo Taburet · signal, images et vélo

Une radio qu’on emporte, une carte qui sait où trouver de l’eau, une façon de cacher un message dans le grain d’une photographie, une photo imprimée en quatre encres qui ne tiennent pas en place, et une rafale de photos qui se joue à l’endroit puis à l’envers. Elles ont moins en commun qu’il n’y paraît, sauf que chacune est partie d’une envie que j’avais.

📻 diapason

Votre propre radio, diffusée depuis un téléphone et jouée en synchro sur toutes les enceintes autour.

🚲 Ravitools

Des fichiers GPX enrichis en points d'eau, de ravitaillement et de bivouac, utilisables hors ligne.

🌾 Stéganographie naturelle

Un schéma d'insertion qui imite le bruit du capteur, rendant la charge statistiquement invisible. Thèse.

🖨️ Trame CMJN

Une photo imprimée en quatre encres tramées, mal repérées et tremblantes, en direct en WebGL.

🪃 Boomerang

Une rafale de photos jouée à l'endroit puis à l'envers en vidéo qui boucle, encodée dans le navigateur.

📻 diapason

Votre propre radio, diffusée depuis un téléphone.

diapason.fm production diapason.studio préproduction

Une personne choisit la musique, et tout le monde autour la joue à voix haute sur sa propre enceinte portable, en synchro. Le téléphone fait le lien entre la station et l’enceinte qu’il pilote, en Bluetooth ou par un câble. Plus il y a de monde, plus le résultat est fort et large.

Le plus dur n’est pas d’envoyer l’audio, c’est de se mettre d’accord sur le moment où le jouer. Chaque téléphone a sa propre horloge et les réseaux mobiles sont imprévisibles, alors tenir un groupe assez serré pour que les enceintes fusionnent en une seule au lieu de baver, c’est là qu’est passé le travail.

Vous créez une station et vous obtenez un code à six caractères et un QR. Vous la pointez vers ce que vous voulez diffuser : un lien, une playlist, votre micro, ou simplement ce que votre ordinateur est déjà en train de jouer. Les autres scannent le code, branchent leur enceinte, et c’est parti. Ceux qui arrivent en retard se calent sur les autres.

Il n’y a rien à installer et pas de compte à créer, parce que tout tourne dans le navigateur. Ça continue de jouer quand un téléphone verrouille son écran ou passe du Wi-Fi à la 4G. Vous pouvez laisser les auditeurs voter pour la suite plutôt que de tout choisir vous-même.

Je l’ai construit pour les sorties vélo.

RustaxumWebAssemblyTypeScriptAstroOpusWeb AudioPWA

🚲 Ravitools

Ce qu’il y a le long de la route, même sans réseau.

Essayer démo Source GitHub

Ravitools enrichit les fichiers GPX avec des points d’intérêt hors ligne (eau, ravitaillement, campings) pour les cyclistes au long cours, qui perdent le réseau exactement là où ils ont le plus besoin de savoir où est le prochain robinet.

Chargez une trace et Ravitools demande à OpenStreetMap ce qu’il y a le long : points d’eau, commerces, restaurants, campings et abris, toilettes, magasins de vélo. Il cherche dans un couloir qui suit la trace plutôt que dans un rectangle autour, puis garde chaque lieu selon sa vraie distance à la ligne, dans un rayon que vous réglez : étroit en ville, large là où il y a peu. Les doublons ne sont fusionnés que quand ça garde du sens sur la route.

Le profil d’altitude colore chaque pente et signale chaque tronçon, plus long qu’une distance que vous choisissez, sans eau ou sans commerce. Ce que vous gardez repart en GPX, KML, KMZ, GeoJSON ou GPX OsmAnd, à charger sur un GPS ou un téléphone avant de partir.

La démo tourne entièrement dans votre navigateur : la trace n’en sort jamais, et c’est le navigateur qui demande lui-même à OpenStreetMap ce qu’il y a le long du chemin. Chercher chaque lieu sur le web demande un serveur, alors la démo laisse cette étape de côté.

TypeScriptReactLeafletGPXOpenStreetMap

🌾 Stéganographie naturelle dans le domaine JPEG

Travaux de thèse, 2017-2020

Un schéma d’insertion qui modélise le bruit de capteur d’un appareil photo, pour qu’une charge cachée soit statistiquement indiscernable du bruit photonique qui était déjà là. Ces travaux établissent une forme close de la matrice de covariance du signal stégo dans le domaine DCT. À la qualité JPEG 100, le schéma transporte environ deux bits par coefficient AC non nul, et un détecteur se trompe encore plus de 40 % du temps (PE ≥ 40 %), quand un pile ou face se tromperait 50 % du temps.

PythonMATLABDCTStéganalyse

Le schéma découpe les blocs 8×8 d’un JPEG en quatre réseaux entrelacés et insère dedans dans l’ordre, de sorte que chaque réseau puisse être conditionné par ceux déjà écrits. Chaque case est un bloc ; survolez-en ou touchez-en une pour voir sa portée, tout ce dont elle dépend de proche en proche :

Un article explicatif, en anglais, présente tout le schéma avec des figures interactives, du capteur au fichier JPEG. Les articles sont sur la page publications.

🖨️ Trame CMJN

Une photo imprimée par une presse qui ne tient pas en place.

En 2021, Matt DesLauriers a publié une photo reconstruite en plaques CMJN tramées. En réponse à quelqu’un, il a donné la recette de l’image : séparer la photo en cyan, magenta, jaune et noir, tramer chaque couche jusqu’à n’avoir plus que des points, puis dessiner un cercle de l’encre correspondante sur chaque point, en multiplication. Il n’a pas dit comment ça bouge, et c’est le mouvement qui donne la profondeur. Je l’ai refait dans le navigateur, en mesurant sa vidéo image par image jusqu’à ce que la mienne bouge pareil.

L’image fixe suit sa recette, avec Floyd-Steinberg pour le tramage. Les cercles débordent un peu de leur cellule, comme l’encre qui s’étale, donc chaque plaque est tramée un peu plus claire pour compenser. Les couleurs sont celles des encres d’imprimerie plutôt que celles de l’écran, sur un papier blanc cassé.

Douze fois par seconde, toute la feuille tremble de moins d’un point, et chaque plaque dérive un peu de son côté. Les deux sont mesurés sur la vidéo. La profondeur vient d’une carte de profondeur estimée par Depth Anything, un réseau de neurones qui devine les distances à partir d’une seule image. Chaque plaque est dessinée comme vue de son propre point de vue, un peu à l’écart des autres et qui se promène : ce qui est proche glisse d’un côté, ce qui est loin de l’autre, et le plan du milieu ne bouge pas. Sur la vidéo, le décalage suit la proximité à la puissance 0,3. Chaque tirage a sa propre presse : tremblement, repérage et rayures sont tirés au hasard autour de ces valeurs.

Deux choses ont mal tourné en route. La première, c’est le moiré. Floyd-Steinberg n’est pas aléatoire : il s’installe dans des chaînes de points et, autour de la moitié d’encre, dans des damiers, et chaque plaque a les siens. Superposés, deux motifs presque réguliers battent en ondes lentes, qui avancent quand les plaques bougent. Du bruit sur le seuil cassait les rangées, pas les chaînes. Maintenant le seuil ondule en bruit bleu : une tuile de seuils classés pour que les cellules sous chacun soient réparties le plus régulièrement possible (le void-and-cluster d’Ulichney), lue à un endroit différent par chaque plaque. La diffusion d’erreur garde la tonalité et les contours, les points se répartissent de façon homogène, et les plaques n’ont plus de motif commun qui puisse battre. Les points sont aussi un peu décalés du centre de leur cellule : sur une grille commune, le recouvrement de deux plaques dépend de leur écart, et cet écart change avec la profondeur.

La seconde, c’est au bord des objets proches. Déplacer chaque point selon la profondeur sous lui empilait les points d’un côté d’un drapeau et ouvrait un trou de l’autre, et ces trous s’ouvraient et se refermaient au gré des points de vue. Maintenant chaque pixel va chercher son encre là où la profondeur sous lui l’indique : rien ne peut s’empiler ni se déchirer. Seul, ça laisserait le fond grignoter le bord du drapeau, donc la carte de profondeur est d’abord gonflée un peu au-delà de la silhouette de chaque objet proche, puis adoucie : le drapeau bouge d’un bloc, et la plaque s’étire sur ce qui est juste derrière lui.

Les jeux Riso sont deux ou trois encres de risographe sur papier crème. Le cyan, le magenta et le jaune ne veulent rien dire pour elles, alors chaque jeu a sa propre séparation : la quantité de chaque encre qui reconstruit le mieux la couleur, par moindres carrés sur leurs densités optiques.

WebGL2GLSLJavaScript

🪃 Boomerang

Une rafale de photos, à l’endroit puis à l’envers.

Essayer démo Source GitHub

Déposez quelques photos prises en rafale et Boomerang les joue à l’endroit, puis à l’envers, en vidéo qui boucle pour Instagram, les Reels ou TikTok : carrée, verticale ou horizontale, avec une marge de la couleur de votre choix.

La boucle se joue en direct sur un canvas pendant que vous la réglez, et la vidéo n’est encodée qu’à l’export. Les photos sont décodées, redressées d’après leur EXIF et cadrées en parallèle dans des workers, puis ffmpeg, compilé en WebAssembly, les encode dans un autre worker en H.264 que les applis acceptent sans broncher. C’était au départ un script Python ; aujourd’hui rien n’est envoyé nulle part, et vos photos ne quittent jamais votre téléphone.

Le cheval en haut de cette page, c’est Sallie Gardner au galop : onze photos qu’Eadweard Muybridge a prises en 1878 avec une rangée d’appareils que la jument déclenchait en passant, l’une des premières rafales jamais prises, passées dans Boomerang.

AstroReactTypeScriptffmpeg.wasmWeb Workers