https://bvdp.inetdoc.net/files/bundle/
http://ccwu.me/vsfm/doc.html#usage
http://ccwu.me/vsfm/doc.html#warning
http://ccwu.me/vsfm/doc.html#nvm
http://combiencaporte.blogspot.fr/2012/07/la-photogrammetrie-visualsfm-et-meshlab.html
https://groups.google.com/forum/?fromgroups#!topic/vsfm/MTTfUI35duQ
http://www.10flow.com/2012/08/15/building-VisualSFM-on-ubuntu-12-04-precise-pangolin-desktop-64-bit
http://www.cs.utexas.edu/users/dml/Software/graclus.html
http://www.di.ens.fr/pmvs/documentation.html
Vidéo pour les différentes étapes: https://www.youtube.com/watch?v=5ceiOd8Yx3g
Super explication avec utilisation combinée avec Meshlab: http://wedidstuff.heavyimage.com/index.php/2013/07/12/open-source-photogrammetry-workflow/
http://www.10flow.com/2012/08/15/building-VisualSFM-on-ubuntu-12-04-precise-pangolin-desktop-64-bit/
sous ubuntu 12.04
sudo apt-get install libc6-dev-i386 libhdf5-serial-dev libgtest-dev libgsl0-dev python-dev cmake imagemagick libmagick++-dev gfortran minpack-dev liblapack-dev libatlas-dev libatlas-base-dev libboost-dev libc6-dev-i386 libgsl0-dev libgtk2.0-dev libglew1.6-dev libglew1.6 libdevil-dev libboost-all-dev libatlas-cpp-0.6-dev libatlas-dev imagemagick libatlas3gf-base libcminpack-dev libgfortran3 libmetis-edf-dev libparmetis-dev freeglut3-dev libgsl0-dev
ou sous ubuntu 15.04
sudo apt-get install libc6-dev-i386 libhdf5-serial-dev libgtest-dev libgsl0-dev python-dev cmake imagemagick libmagick++-dev gfortran minpack-dev liblapack-dev libatlas-dev libatlas-base-dev libboost-dev libc6-dev-i386 libgsl0-dev libgtk2.0-dev libglew1.6-dev glew-utils libdevil-dev libboost-all-dev libatlas-cpp-0.6-dev libatlas-dev imagemagick libatlas3gf-base libcminpack-dev libgfortran3 libmetis-edf-dev libparmetis-dev freeglut3-dev libgsl0-dev
ou sous ubuntu 16.04
sudo apt-get install libc6-dev-i386 libhdf5-serial-dev libgtest-dev libgsl0-dev python-dev cmake imagemagick libmagick++-dev gfortran minpack-dev liblapack-dev libatlas-dev libatlas-base-dev libboost-dev libc6-dev-i386 libgsl0-dev libgtk2.0-dev libglew1.6-dev glew-utils libdevil-dev libboost-all-dev libatlas-cpp-0.6-dev libatlas-dev imagemagick libatlas3-base libcminpack-dev libgfortran3 libmetis-edf-dev libparmetis-dev freeglut3-dev libgsl0-dev f2c
cd ~ mkdir vsfm cd vsfm
#récupération de SiftGPU-V400.zip sur http://wwwx.cs.unc.edu/~ccwu/cgi-bin/siftgpu.cgi
wget http://wwwx.cs.unc.edu/~ccwu/cgi-bin/siftgpu.cgi mv siftgpu.cgi SiftGPU-V400.zip unzip SiftGPU-V400.zip cd SiftGPU/ nano makefile ajouter apres le 1° endif: siftgpu_enable_cuda = 0 make mkdir -p ../vsfm/bin cp bin/libsiftgpu.so ../vsfm/bin cd ..
#la version 1.0.4 n'existe plus pba_v1.0.4.zip (1021 KB)
wget http://grail.cs.washington.edu/projects/mcba/pba_v1.0.5.zip unzip pba_v1.0.5.zip cd pba mv makefile makefile_gpu cp makefile_no_gpu makefile make cd ..
#comme j'ai compilé la version sans gpu et que visualsfm compte utiliser la version avec, il faut que j'adapte le nom de la lib binaire…. à tester…
cd pba/bin ln -s libpba_no_gpu.so libpba.so cd ../../
wget http://www.di.ens.fr/pmvs/pmvs-2.tar.gz tar xf pmvs-2.tar.gz cd pmvs-2/program/main/ cp mylapack.o mylapack.o.backup make clean cp mylapack.o.backup mylapack.o make depend make cd ../../../
#depuis http://www.cs.utexas.edu/users/dml/Software/graclus.html
wget http://www.cs.utexas.edu/users/dml/Software/graclus1.2.tar.gz tar xvf graclus1.2.tar.gz cd graclus1.2/ nano Makefile.in set “-DNUMBITS=64″ make cd ..
wget http://ccwu.me/vsfm/download/VisualSFM_linux_64bit.zip unzip VisualSFM_linux_64bit.zip cd vsfm make bin/VisualSFM cd ..
wget http://www.di.ens.fr/cmvs/cmvs-fix2.tar.gz tar xf cmvs-fix2.tar.gz cp pmvs-2/program/main/mylapack.o cmvs/program/main/ nano cmvs/program/base/cmvs/bundle.cc #ajouter au début #include <vector> #include <numeric> nano cmvs/program/main/genOption.cc #ajouter au début #include <stdlib.h> nano cmvs/program/main/Makefile #Your INCLUDE path (e.g., -I/usr/include) YOUR_INCLUDE_PATH = #Your metis directory (contains header files under graclus1.2/metisLib/) YOUR_INCLUDE_METIS_PATH = -I/home/bvandepo/vsfm/graclus1.2/metisLib #Your LDLIBRARY path (e.g., -L/usr/lib) YOUR_LDLIB_PATH = -L/home/bvandepo/vsfm/graclus1.2
cd ~/vsfm/cmvs/program/main make cp cmvs ~/vsfm/vsfm/bin cp pmvs2 ~/vsfm/vsfm/bin cp genOption ~/vsfm/vsfm/bin cd ~/vsfm
archivage des fichiers d'installation:
mkdir archive mv cmvs-fix2.tar.gz graclus1.2.tar.gz pba_v1.0.5.zip pmvs-2.tar.gz SiftGPU-V400.zip VisualSFM_linux_64bit.zip archive
ajouter dans ~/.bashrc:
nano ~/.bashrc export PATH=$PATH:/home/bvandepo/vsfm/vsfm/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/bvandepo/vsfm/vsfm/bin:/home/bvandepo/vsfm/SiftGPU/bin/:/home/bvandepo/vsfm/pba/bin/ source ~/.bashrc
echo $LD_LIBRARY_PATH
pour lancer:
VisualSFM &
en cas de problème de librairie:
ldd ./vsfm/bin/VisualSFM
documentation http://ccwu.me/vsfm/doc.html#
installation de meshlab pour visualiser les modèles .ply
sudo apt-get install meshlab
File → open +multi images→charger les pgm
sfm →pairwise matching→ compute missing matches
sfm → reconstruct sparse
selectionner les caméras qui posent probleme
bouton main grise ?→delete selected camera
sfm→pairwise matching→show spanning forest et matrix
bouton triangle rouge et bleu: compute 3D reconstruction
bouton cmvs⇒ choisir dossier /tmp/img sur ramdisk et donner un nom au fichier
view→dense 3D points
si il y a un problème lors du bundle à cause du choix des 2 images de références, relancer le bundle après avoir fait:
Sfm->Pairwise Matching->Update Pairwise F-Matrix
sauvegarde du résultat en nvm ou ply
Sfm->Extra Function->Save Current Model
au cas ou il y aurait plusieurs modèles générés
Sfm->More options->Merge sparse model puis relancer BA Sfm->More options->Find more points puis relancer BA
pour afficher les correspondances entre les images:
View->feature match Resume 3D reconstruction peut enlever des mauvais matches
Imposer des paramètres intrisèques fixés:
Sfm->More function->Set fixed calibration
format attendu
fx cx fy cy r 2605.73990 1364.50522 2612.01336 983.24601 0
~/cartography/sequences/enac_ulysse/vol2$ VisualSFM -h
+sort: keep the input image order in the output NVM; +fixcam: keep existing cameras unmodified.
#!/bin/bash IMG_DIR="select/" mkdir -p $IMG_DIR LIST_FILE=$IMG_DIR"list.txt" rm $LIST_FILE rm $IMG_DIR/image_*.pgm rm $IMG_DIR/image_*.png rm $IMG_DIR/image_*.jpg rm $IMG_DIR/image_*.tif rm $IMG_DIR/image_*.sift rm $IMG_DIR/image_*.mat rm $IMG_DIR/*.nvm #copie des images avec des noms consécutifs j=0 #paramètres de seq image de départ, incrément entre chaque image, image de fin #for i in $(seq -w 1 40 3769); do #for i in $(seq -w 100 3 400); do for i in $(seq -w 1 30 3769); do #formate sur 4 digits if=`printf "%04.f\n" $i` jf=`printf "%04.f\n" $j` echo $if" -> "$jf cp image_$if.pgm $IMG_DIR/image_$jf.pgm #convert image_$i.pgm select/image_$k.tif j=`expr $j + 1` done #génération de la liste des paires d'images for k in $(seq -w 1 120); do for inc in $(seq 1 5); do l=`expr $k + $inc` #formatage sur 4 digits kf=`printf "%04.f\n" $k` lf=`printf "%04.f\n" $l` echo image_$kf.pgm image_$lf.pgm >>$LIST_FILE done done
#!/usr/bin/env /bin/bash USER_DATA=select OUTPUT_DATA=select/results OUTPUT_NVM=${OUTPUT_DATA}.nvm if [ "$1" = "clean" ]; then rm -rf $OUTPUT_NVM ${USER_DATA}/*.mat ${USER_DATA}/*.sift echo "Done cleaning. Leaving" exit 0 fi HOMEREP=/home/bvandepo/ export PATH=$HOMEREP/vsfm/cmvs/program/main:$HOMEREP/vsfm/vsfm/bin:$PATH export LD_LIBRARY_PATH=$HOMEREP/vsfm/pba/bin/:$HOMEREP/vsfm/vsfm/bin:$HOMEREP/vsfm/SiftGPU/bin/:$LD_LIBRARY_PATH #VisualSFM sfm+pmvs+sort $USER_DATA/list.txt $OUTPUT_NVM VisualSFM sfm+pmvs+sort list.txt result.nvm VisualSFM sfm+sort list.txt result.nvm VisualSFM sfm+sort result.nvm
VisualSFM Version = 0.5.26 ------------------------------------------------ VisualSFM sfm[options] input output.nvm [user_data_path] options = [match_option][sfm_option][misc_option][mvs_option] match_option = [+pairs/+import/+subset/+nomatch/] +pairs: match image pairs from [user_data_path]; use @range,step as path for sequence mode; +import: load feature matches from [user_data_path]; +subset: enable preemptive feature matching when #images >= param_preemptive_switch; +nomatch: reconstruction without feature matching; default: compute missing pairwise matches. sfm_option = [+resume/+add/+skipsfm/+loadnvm/] +resume: load NVM file, try add new images from [input].txt, and grow the existing models; +add: load NVM file, and find more points and projections for the existing models; +loadnvm: load NVM file and skip feature matching; +skipsfm: skip sparse and dense reconstruction; default: run regular sparse reconstruction. misc_option = [+k=fx,cx,fy,cy/+shared][+sort][+gcp][+fixcam][+merge] +k: fixed calibration, e.g. +k=1024,800,1024,600; +shared: enforce shared calibration in the end; +sort: keep the input image order in the output NVM; +gcp: load [input].gcp and transform the 3D model. +fixcam: keep existing cameras unmodified. +merge: try model merging after sparse reconstruction mvs_option = [+pmvs/+cmvs/+cmp/] +cmvs: undistort images, run CMVS/genOption, skip PMVS; +pmvs: undistort images, run CMVS/genOption/PMVS; +cmp: undistort images, write p-matrices for CMP-MVS; default: skip the entire dense reconstruction. The <input> can be the following: a .txt file containing relative/absolute image paths, a folder path to look for .jpg files, or an existing NVM file. ------------------------------------------------ VisualSFM listen[+log] port Start the GUI and listen to a socket port for UI commands, which simulate menu clicks. Each command should in the form of "id[c][s] [argument]\n". The [id] is an integer that corresponds to a menu item, for which the complete list can be found in the sample ui.ini file. The optional flag [c][s] corresponds CTRL and SHIFT press; The [argument] is for the input string like filepath. Log messages will be send to client if +log is specified puis relancer BA ------------------------------------------------ VisualSFM sfm[export_op puis relancer BAtions] input output.txt +exportp: export putative feature matches +exportf: export F-matrix inlier matches ------------------------------------------------ VisualSFM siftgpu[+ascii] image_list_file Detect features for a list of images
[1] 21712 bvandepo@garossos:~$ CPU single-precisoin solver; 2 cores. Reading bundle...40 cameras -- 22512 points in bundle file *********** 40 cameras -- 22512 points Reading images: **************************************** Set widths/heights...done 0 secs done 0 secs slimNeighborsSetLinks...done 0 secs mergeSFM...***********resetPoints...done Rep counts: 22512 -> 509 1 secs setScoreThresholds...done 0 secs sRemoveImages... ********** Kept: 3 4 5 6 7 8 9 10 12 13 16 17 18 19 23 24 25 26 28 29 30 31 32 33 34 35 36 37 38 39 Removed: 0 1 2 11 14 15 20 21 22 27 sRemoveImages: 40 -> 30 0 secs slimNeighborsSetLinks...done 0 secs Cluster sizes: 30 Adding images: 0 Image nums: 40 -> 30 -> 30 Divide: done 0 secs 27.8667 images in vis on the average -------------------------------------------------- --- Summary of specified options --- # of timages: 30 (enumeration) # of oimages: 0 (enumeration) level: 1 csize: 2 threshold: 0 wsize: 7 minImageNum: 3 CPU: 2 useVisData: 1 sequence: -1 -------------------------------------------------- Reading images: ****************************** 3 Harris running ...4 Harris running ...1876 harris done DoG running...2010 harris done DoG running...2699 dog done 5 Harris running ...2638 dog done 6 Harris running ...1946 harris done DoG running...1978 harris done DoG running...2654 dog done 7 Harris running ...2095 harris done DoG running...2653 dog done 8 Harris running ...2693 dog done 9 Harris running ...2000 harris done DoG running...2050 harris done DoG running...2598 dog done 10 Harris running ...2637 dog done 12 Harris running ...1990 harris done DoG running...1796 harris done DoG running...2692 dog done 13 Harris running ...2644 dog done 16 Harris running ...1862 harris done DoG running...1948 harris done DoG running...2728 dog done 17 Harris running ...2567 dog done 18 Harris running ...1910 harris done DoG running...2061 harris done DoG running...2680 dog done 19 Harris running ...2688 dog done 23 Harris running ...1970 harris done DoG running...2015 harris done DoG running...2699 dog done 24 Harris running ...2600 dog done 25 Harris running ...1992 harris done DoG running...1822 harris done DoG running...2551 dog done 26 Harris running ...2662 dog done 28 Harris running ...1942 harris done DoG running...2079 harris done DoG running...2702 dog done 29 Harris running ...2010 harris done DoG running...2610 dog done 30 Harris running ...2567 dog done 31 Harris running ...1939 harris done DoG running...1926 harris done DoG running...2519 dog done 32 Harris running ...1964 harris done DoG running...2604 dog done 33 Harris running ...2607 dog done 34 Harris running ...2046 harris done DoG running...1984 harris done DoG running...2633 dog done 35 Harris running ...2505 dog done 36 Harris running ...1966 harris done DoG running...1974 harris done DoG running...2634 dog done 37 Harris running ...1908 harris done DoG running...2630 dog done 38 Harris running ...2604 dog done 39 Harris running ...1911 harris done DoG running...1925 harris done DoG running...2604 dog done 2555 dog done done adding seeds (4,4269)(28,4300)(11,3664)(15,4133)(16,1936)(24,4317)(17,1843)(26,3458)(29,4113)(9,1592)(22,1900)(19,351)(3,2927)(2,424)(23,332)(25,310)(18,0)(13,276)(8,291)(0,1252)(21,1434)(7,531)(12,13)(14,19)(20,5)(5,2004)(6,2)(10,2)(1,9)(27,5)done ---- Initial: 0 secs ---- Total pass fail0 fail1 refinepatch: 145847 88328 48965 8554 96882 Total pass fail0 fail1 refinepatch: 100 60.5621 33.5729 5.86505 66.4271 Expanding patches... ---- EXPANSION: 2829 secs ---- Total pass fail0 fail1 refinepatch: 924156 847591 58111 18454 866045 Total pass fail0 fail1 refinepatch: 100 91.7151 6.28801 1.99685 93.712 FilterOutside mainbody: Gain (ave/var): 1.44734 2.87679 893293 -> 611767 (68.4845%) 0 secs Filter Exact: ****************************** 611767 -> 292769 (47.8563%) 0 secs FilterNeighbor: 292769 -> 234085 (79.9555%) 0 secs FilterGroups: 23 234085 -> 194522 (83.0989%) 0 secs STATUS: 16614 0 946311 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Expanding patches... ---- EXPANSION: 2659 secs ---- Total pass fail0 fail1 refinepatch: 1074636 589061 108676 376899 965960 Total pass fail0 fail1 refinepatch: 100 54.8149 10.1128 35.0722 89.8872 FilterOutside mainbody: Gain (ave/var): 2.28291 2.07301 783583 -> 713287 (91.0289%) 0 secs Filter Exact: ****************************** 713287 -> 351883 (49.3326%) 0 secs FilterNeighbor: 351883 -> 320880 (91.1894%) 0 secs FilterGroups: 32 320880 -> 276521 (86.1758%) 0 secs STATUS: 38079 0 1890801 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Expanding patches... ---- EXPANSION: 2338 secs ---- Total pass fail0 fail1 refinepatch: 1045429 553496 105713 386220 939716 Total pass fail0 fail1 refinepatch: 100 52.9444 10.1119 36.9437 89.8881 FilterOutside mainbody: Gain (ave/var): 2.28821 2.04883 830017 -> 754364 (90.8854%) 0 secs Filter Exact: ****************************** 754364 -> 368196 (48.8088%) 0 secs FilterNeighbor: 368196 -> 338478 (91.9288%) 0 secs FilterGroups: 33 338478 -> 292789 (86.5016%) 0 secs STATUS: 58848 0 2809745 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ---- Total: 0 secs ---- Running Yasutaka Furukawa's CMVS tool... cmvs /home/bvandepo/sample/mvs.nvm.cmvs/00/ 50 2 genOption /home/bvandepo/sample/mvs.nvm.cmvs/00/ 1 2 0,700000 7 3 2 1 cluster is generated for pmvs reconstruction. pmvs2 /home/bvandepo/sample/mvs.nvm.cmvs/00/ option-0000 This may take a little more time, waiting... 8501 seconds were used by PMVS Loading option-0000.ply, 292789 vertices ... Loading patches and estimating point sizes.. ############################# You can manually remove bad MVS points: 1. Switch to dense MVS points mode; 2. Hit F1 key to enter the selection mode; 3. Select points by dragging a rectangle; 4. Hit DELETE to delete the selected points. ############################# Save to mvs.nvm ... done Save /home/bvandepo/sample/mvs.0.ply ...done ---------------------------------------------------------------- Run dense reconstruction, finished Totally 142,467 minutes used
tuto en francais: http://combiencaporte.blogspot.fr/2012/07/la-photogrammetrie-visualsfm-et-meshlab.html
Filter→ Sampling / Poisson-disk Sampling.
La case Base mesh subsampling doit être cochée (car pour l'instant les éléments du maillage n'existent pas). Number of samples: 10000 Création d'un petit nuage de point contenant environ 10k points, en appliquant la méthode de rééchantillonnage vue ci-dessus. On applique ensuite sur ce petit échantillon
Filter→ Point Set / Compute Normals for Point Set,
avec la case Flip normals w.r.t. viewpoint cochée8, et en entrant les coordonnées d'un point fictif éloigné du maillage (par exemple 0,0,-1000).
Filters→ Remeshing, simplification and reconstruction → Surface Reconstruction : Poisson,
avec Octree Depth égal à 6. Transférer ensuite les normales de ce maillage vers le nuages de points complets, avec
Filters→Sampling / Vertex Attribute Transfer
en cochant uniquement Transfer normal, et en choisissant votre premier maillage (poisson mesh?????) pour Source mesh et votre nuage de points complet pour Target mesh. Il est possible de remplacer ces deux premières étapes en appliquant directement le filtre Compute Normals for Point Set au nuage de points complet, si ce dernier est suffisamment petit. Si le nuage est trop grand, l'application du filtre peut-être très longue ou faire planter MeshLab.
Filters→Remeshing, simplification and reconstruction / Surface Reconstruction : Poisson,
en choisissant Octree Depth entre 6 et 12 selon la précision du maillage désiré, et Solver Divide entre la valeur de Octree Depth et cette valeur moins 2. Attention le temps de calcul augmente très rapidement avec Octree Depth, et il vaut mieux commencer avec Octree Depth égal à 6 et l'augmenter de 1 en 1. L'effet de la valeur de Octree Depth est illustrée sur la figure 4. Sur cet exemple on voit le raffinement du maillage au fur et à mesure que le paramètre Octree Depth augmente9. A la fin de l'étape (3), on obtient donc le maillage recherché, mais il ne possède pour l'instant pas de couleur.
Pour transférer les couleurs contenues dans le nuage de point sur votre nouveau maillage, appliquez Sampling / Vertex Attribute transfer, en cochant Transfer color, et en choisissant votre nuage de points pour Source mesh et votre nouveau maillage pour Target mesh.
Filter→ Point Set / Compute Normals for Point Set,
avec la case Flip normals w.r.t. viewpoint cochée8, et en entrant les coordonnées d'un point fictif éloigné du maillage (par exemple 0,0,-10000).
Problème, la moitié des normales est inversée….