Movie2Gcode

De fablabo
Révision de 11 mai 2014 à 15:16 par Cedric (discussion | contributions) (boucle de traitement)

Aller à : navigation, rechercher


copier un film avec une imprimante 3D

Horse.profil.jpg

Contributeur·ice·s

Statut du projet

Prototype

Statut de la publication

License

CC-by-sa-3.0

Inspiration

Fichiers source

Machines

Matériaux

Lien




Résumé

à l'occasion du travail de la semaine à la fabacademy, je dois concevoir un programme qui interface un ordinateur avec un capteur ou un actionneur.

J'ai choisi de finaliser un projet qui me tiend à coeur : copier un film avec une imprimante 3D

principe de fonctionnement

Un film est décomposé en photogrammes qui sont induviduellement :

  • vectorisés
  • transformé en STL
  • compilé en GCode

à la fin les Gcodes sont empilés, de manière à obtenir un objet 3D dont chaque couche est un photogramme du film.

Le résultat est une décomposition spaciale du mouvement.

problèmes rencontrés

Le point dur est le passage en 3D.

Il existe dans fabmodules gif_stl qui transforme un gif en stl exactement sur ces modalités.

Hélas, il produit des trous dans le maillage résultant (j'ai l'impression que ça correspond aux endroits où les couches n'ont pas le même nomre de pixels pleins).

Ce défaut n'est pas trop grave pour un objet relativement petit, mais pour un film contenant plusieurs centaines d'images, cela provoque un travail de postproduction long et compliqué.


J'ai donc envisagé d'utiliser openscad pour transformer les images en STL.

Mon but initial était de réaliser un STL global de tout le film.

Hélas, openscad utilise beaucoup de ressources, particulièrement pour extruder des dxf. Je n'ai pas réussi à faire un calcul dans des temps raisonnables.


Finalement, je suis arrivé à une solution : openscad réalise un STL par image, puis je calcule le Gcode. à la fin, je compile tous les gcodes pour obtenir un fichier de fabrication complet.

Ce résultat a une caractéristique amusante : je construit un objet 3D sans jamais avoir de maillage global de l'objet, mais j'obtiens quand même un objet réel.


le programme

Comme la chaîne de conversion utilise de nombreux programmes, j'ai réalisé un premier programme en bash :

extraction des images fixes

avec ffmpeg :

fmpeg -i RaceHorseMuybridge.flv images/image-%3d.bmp

le reste des transformations se réalisent en boucle pour chaque image

boucle de traitement

function demon(){

echo "traitement de toutes les images image-$1*.bmp"; for i in image-$1*.bmp; do


       if [ -f ${i} ] 
           then
               	echo "_________________________________________________________${i}";

potrace -o ${i%bmp}eps -k 0.6 -t 50 -B-0.25 -e ${i}; #potrace -o ${i%bmp}eps -k 0.43 --tight -M -0.41 -e ${i}; pstoedit -dt -f dxf:-polyaslines ${i%bmp}eps ${i%bmp}dxf; rm ${i%bmp}eps #ecrit le fichier openscad echo "intersection(){ translate([-4,0,-5])cube([96,63,10]);scale([15,15,1])linear_extrude(height = 0.15, center = false, convexity = 10) import (file = \"${i%bmp}dxf\");}translate([-4,0,0])cube(0.05); translate([91.95,62.95,0])cube([0.05,0.05,0.14]);" > ${i%bmp}scad; echo "calcul du ${i%bmp}STL"; /home/cedric/soft/openscad/openscad -o ../stl/${i%bmp}stl ${i%bmp}scad; rm ${i%bmp}scad; rm ${i%bmp}dxf; echo "_______________________________________${i%bmp}STL ok";

           else
               echo ${i} existe -----------------pas;
       fi

done

}

vectorisation

Pour définir du plein et du vide à partir d'images en valeurs de lumière, je vectorise les images avec potrace


potrace -o ${i%bmp}eps -k 0.6 -t 50 -B-0.25 -e ${i};

openSCAD n'accepte que le format DXF, et potrace en produit, mais une variante non lisible par openSCAD

Je suis donc passé par le format EPS, transformé ensuite en DXF via pstoedit


pstoedit -dt -f dxf:-polyaslines ${i%bmp}eps ${i%bmp}dxf;

création du STL

pour chaque image, je construit un STL à l'aide d'openscad :

intersection(){

 translate([-4,0,-5])cube([96,63,10]);
 scale([15,15,1])
 linear_extrude(height = 0.15, center = false, convexity = 10)
 import (file = \"${i%bmp}dxf\");

}translate([-4,0,0])cube(0.05); translate([91.95,62.95,0]) cube([0.05,0.05,0.14]);