Skip to content

Instantly share code, notes, and snippets.

@hy9be
Forked from patriciogonzalezvivo/SFM.md
Created July 11, 2017 02:50
Show Gist options
  • Save hy9be/85383241afebd00dfc1aa1832ff1b77d to your computer and use it in GitHub Desktop.
Save hy9be/85383241afebd00dfc1aa1832ff1b77d to your computer and use it in GitHub Desktop.
SfM Tools

Probably the most straight forward way to start generating Point Clouds from a set of pictures.

VisualSFM is a GUI application for 3D reconstruction using structure from motion (SFM). The reconstruction system integrates several of my previous projects: SIFT on GPU(SiftGPU), Multicore Bundle Adjustment, and Towards Linear-time Incremental Structure from Motion. VisualSFM runs fast by exploiting multicore parallelism for feature detection, feature matching, and bundle adjustment.

For dense reconstruction, this program supports Yasutaka Furukawa's PMVS/CMVS tool chain, and can prepare data for Michal Jancosek's CMP-MVS. In addition, the output of VisualSFM is natively supported by Mathias Rothermel and Konrad Wenzel's SURE.

Dan’s Monaghan wrote a script that will compile VisualSfM on MacOS you.

Before that you should installing some basic dependences:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Compile

To compile VisualSfM on Mac Yosemite (OS X 10.10) I have fork and modify Dan’s Monaghan script. Clone it and run it.

git clone [email protected]:tangrams/VisualSFM_OS_X.git
cd VisualSFM_OS_X
./vsfm_os_x_installer.sh

Install

You can run VisualSfM directly from these folder. I really like been able to execute it from any where on my system. For that:

cd vsfm/bin
mv *.so /usr/local/lib 
mv * /usr/local/bin

Uninstall

To uninstall VisualSfM from your system you just need to:

rm /usr/local/bin/VisualSFM
rm /usr/local/bin/cmvs
rm /usr/local/bin/genOption
rm /usr/local/bin/pmvs2
rm /usr/local/lib/libsiftgpu.so
rm /usr/local/lib/libpba.so

Bundler is a structure-from-motion (SfM) system for unordered image collections (for instance, images from the Internet) written in C and C++. An earlier version of this SfM system was used in the Photo Tourism project. For structure-from-motion datasets, please see the BigSFM page.

Bundler takes a set of images, image features, and image matches as input, and produces a 3D reconstruction of camera and (sparse) scene geometry as output. The system reconstructs the scene incrementally, a few images at a time, using a modified version of the Sparse Bundle Adjustment package of Lourakis and Argyros as the underlying optimization engine. Bundler has been successfully run on many Internet photo collections, as well as more structured collections.

The Bundler source distribution also contains potentially userful implementations of several computer vision algorithms, including:

  • F-matrix estimation

  • Calibrated 5-point relative pose

  • Triangulation of multiple rays

Bundler produces sparse point clouds. For denser points, Dr. Yasutaka Furukawa has written a beautiful software package called PMVS2 for running dense multi-view stereo. A typical pipeline is to run Bundler to get camera parameters, use the provided Bundle2PMVS program to convert the results into PMVS2 input, then run PMVS2. You might also be interested in Dr. Furukawa's CMVS view clustering software, which is a helpful preprocess to running PMVS2.

Install dependences

git clone git://github.com/vlfeat/vlfeat.git
cd vlfeat
make
cd bin/maci64
cp sift /usr/local/bin
cp aib /usr/local/bin
cp mser /usr/local/bin
cp libvl.dylib /usr/local/lib
brew install jhead
brew install ceres-solver 
brew install imagemagick
  • install python Pillow image library (ex-PIL)
pip install Pillow

Compile the binaries

Download Bundler code and modify the makefile to compile on OS X

git clone [email protected]:snavely/bundler_sfm.git
cd bundler_sfm
cp src/Makefile src/Makefile.bkp
sed -e 's/\-lgfortran//g' src/Makefile.bkp > src/Makefile 
open src/Makefile

Add -I/usr/local/include/ in the INCLUDE_PATH and -L/usr/local/lib to the LIB_PATH in order to look like:

INCLUDE_PATH=-I../lib/imagelib -I../lib/sfm-driver -I../lib/matrix  \
    -I../lib/5point -I../lib/sba-1.5 -I../lib/ann_1.1_char/include  \
    -I../include -I/usr/local/include/

LIB_PATH=-L../lib -L../lib/ann_1.1_char/lib -L/usr/local/lib

Then modify the make file on minpack to point to the right fortran compiler

open lib/minpack/Makefile

Change FC=gcc for FC=gfortran

make

Create a VLFEAT to Lowe's SIFT convertion script

touch ToLoweSift.sh
chmod +x ToLoweSift.sh
mv ToLoweSift.sh /usr/local/bin
open /usr/local/bin/ToLoweSift.sh

Copy and paste:

#!/bin/sh

for file in "$@"; do
    echo "Treating $file" 
    if [ "${file##*.}" == "gz" ]; then
        echo "Uncompressing to ${file%.key.gz}.key"
        gzip -d "$file"
        echo "Converting ${file%.key.gz}.sift"
        cat "${file%.key.gz}.key" | wc -l | awk '{ print $1 " 128" }' > "${file%.key.gz}.sift"
        cat "${file%.key.gz}.key" | awk 'BEGIN { split("4 24 44 64 84 104 124 132", offsets); } { i1 = 0; tmp = $1; $1 = $2; $2 = tmp; for (i=1; i<9; i++) { i2 = offsets[i]; out = ""; for (j=i1+1; j<=i2; j++) { if (j != i1+1) { out = out " " }; out = out $j }; i1 = i2; print out } }' >> "${file%.key.gz}.sift"
        echo "Replacing ${file%.key.gz}.sift for ${file%.key.gz}.key"
        rm "${file%.key.gz}.key"
        mv ${file%.key.gz}.sift ${file%.key.gz}.key
        echo "Compressing ${file%.key.gz}.key"
        gzip -f ${file%.key.gz}.key
    else
        echo "Converting to ${file%.key}.sift"
        cat "$file" | wc -l | awk '{ print $1 " 128" }' > "${file%.key}.sift"
        cat "$file" | awk 'BEGIN { split("4 24 44 64 84 104 124 132", offsets); } { i1 = 0; tmp = $1; $1 = $2; $2 = tmp; for (i=1; i<9; i++) { i2 = offsets[i]; out = ""; for (j=i1+1; j<=i2; j++) { if (j != i1+1) { out = out " " }; out = out $j }; i1 = i2; print out } }' >> "${file%.key}.sift"
        echo "Replacing ${file%.key}.sift for ${file%.key}.key"
        rm "${file%.key}.sift"
        mv ${file%.key}.sift ${file%.key}.key
        echo "Compressing ${file%.key}.key"
        gzip -f ${file%.key}.key
    fi
done

Tweak the scripts

If you are using VLfeat you need to change things here and there to make everything work for you.

open bin/toSift.sh

According to this article we have to replace:

echo "mogrify -format pgm $IMAGE_DIR/$d; $SIFT < $pgm_file > $key_file; rm $pgm_file; gzip -f $key_file"

for

echo "wc -l $key_file.vlfeat | awk '{ print \$1 \" 128\" }' > $key_file"
echo "awk 'BEGIN { split("4 24 44 64 84 104 124 132", offsets); } { i1 = 0; tmp = $1; $1 = $2; $2 = tmp; for (i=1; i<9; i++) { i2 = offsets[i]; out = ""; for (j=i1+1; j<=i2; j++) { if (j != i1+1) { out = out " " }; out = out $j }; i1 = i2; print out } }' >> $key_file.key”
echo "rm $key_file.vlfeat"

Then we should do something similar on toSiftList.sh to match the format vlfeat-sift, also we need to correct the location of mogrify and erase the gzip -f call.

open bin/toSiftList.sh

And replace:

awk "{pgm = \$1; key = \$1; sub(\"jpg\$\", \"pgm\", pgm); sub(\"jpg\$\", \"key\", key); print \"/usr/bin/mogrify -format pgm \" \$1 \"; $SIFT < \" pgm \" > \" key \"; gzip -f \" key \"; rm \" pgm}" $IMAGE_LIST

for

awk "{pgm = \$1; key = \$1; sub(\"jpg\$\", \"pgm\", pgm); sub(\"jpg\$\", \"key\", key); print \"/usr/local/bin/mogrify -format pgm \" \$1 \"; $SIFT \" pgm \" -o \" key \"; rm \" pgm}" $IMAGE_LIST 

Then open and edit paths on RunBundler.sh to match your system.

open RunBundler.sh

Replace:

BASE_PATH=$(dirname $(which $0));

for

BASE_PATH="/usr/local";

Also RunBundler.sh use toSiftList.sh which still export to VLfeat style so we need to add the following block of code after sh sift.txt (approx. line 92):

### Convert VLFeat's keys to Lowe's
for file in *.key; do
  cat "$file" | wc -l | awk '{ print $1 " 128" }' > "${file%.key}.sift"
  cat "$file" | awk 'BEGIN { split("4 24 44 64 84 104 124 132", offsets); } { i1 = 0; tmp = $1; $1 = $2; $2 = tmp; for (i=1; i<9; i++) { i2 = offsets[i]; out = ""; for (j=i1+1; j<=i2; j++) { if (j != i1+1) { out = out " " }; out = out $j }; i1 = i2; print out } }' >> "${file%.key}.sift"
done

Then comment the gzip -d *.gz line that follows the echo "[- Matching keypoints (this can take a while) -]" and modyfy the next line to search for .sift files instead of .key onese. It should look like this:

# Match images (can take a while)
echo "[- Matching keypoints (this can take a while) -]"
awk '{print $1}' $IMAGE_LIST | sed 's/\.jpg$/\.sift/' > list_keys.txt

Finally if you follow this tutorial or you are using a Homebrew Python flavor edit the header of bundler.py.

open utils/bundler.py

And replace

#!/usr/bin/python

to

#!/usr/local/bin/python

Install

Once we are sure everything is working and pointing to the right paths move them to you /usr/local path to install them on the system

mv RunBundler.sh /usr/local/bin
cd bin/
rm zlib1.dll
mv *.so /usr/local/lib
mv * /usr/local/bin
cd ../utils
mv * /usr/local/bin

Uninstall

Just remove the files we copy

rm /usr/local/bin/RunBundler.sh
rm /usr/local/bin/ToSift.sh
rm /usr/local/bin/ToSiftList.sh
rm /usr/local/bin/bundler.py
rm /usr/local/bin/bundler
rm /usr/local/bin/Bundle2Ply
rm /usr/local/bin/Bundle2PMVS
rm /usr/local/bin/Bundle2Vis
rm /usr/local/bin/extract_focal.pl
rm /usr/local/bin/KeyMatchFull
rm /usr/local/bin/RadialUndistort
rm /usr/local/lib/libANN_char.so
rm /usr/local/bin/sift
rm /usr/local/bin/aib
rm /usr/local/bin/mser
rm /usr/local/lib/libvl.dylib

"Open Multiple View Geometry" is a library for computer-vision scientists and especially targeted to the Multiple View Geometry community. It is designed to provide an easy access to the classical problem solvers in Multiple View Geometry and solve them accurately.

git clone --recursive https://github.com/openMVG/openMVG.git
mkdir openMVG_Build
cd openMVG_Build
cmake -DCMAKE_BUILD_TYPE=RELEASE -G "Xcode" . ../openMVG/src/

If you want enable unit tests and examples to the build:

cmake -DCMAKE_BUILD_TYPE=RELEASE -DOpenMVG_BUILD_TESTS=ON -DOpenMVG_BUILD_EXAMPLES=ON -G "Xcode" . ../openMVG/src/
xcodebuild -configuration Release
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment