Code for CVPR 2017 paper --- Distinguishing the Indistinguishable: Exploring Structural Ambiguities via Geodesic Context
This repository contains the code for our Structure-from-Motion Disambiguation work [1]. It offers a way to distinguish the incorrect feature connections caused by ambiguous image content and recover a unified 3D model.
I rewrite the code in order to be contribution-independent and easily-accessible using bundler_sfm, which helps to conduct the incremental Structure-from-Motion calculation. For more robust results, it is recommended to adopt some more recent softwares, like VisualSFM (used in our paper) or COLMAP, and accordingly you may need to do a little bit of revision to the interface module. The code is licensed under the GNU General Public License. If you use it for your research, please cite the following paper in your work:
[1] Qingan Yan, Long Yang, Ling Zhang, Chunxia Xiao. Distinguishing the Indistinguishable: Exploring Structural Ambiguities via Geodesic Context. CVPR 2017.
@inproceedings{yan2017distinguishing,
author={Yan, Qingan and Yang, Long and Zhang, Ling and Xiao, Chunxia},
title={Distinguishing the indistinguishable: Exploring structural ambiguities via geodesic context},
booktitle={IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
pages={3836-3844},
year={2017},
organization={IEEE}
}
For more information, please see my homepage at https://yanqingan.github.io/. If you have any question, please post it here or send an email to me. Sorry that, I may not respond to you immediately, but I will reach out (suppose I do not forget), if I have spare time beyond R&D work and kissing my little baby.
There is currently only one folder ("bundler_sfm_disambiguation" which means it is based on bundler_sfm method) in the directory, in which contains a "src" folder, a "script" folder and a .zip file.
Folder "src":
1. "Disambiguate.cpp" is the core algorithm implementation file which includes all the steps described in our work [1], where ComputeConstraintTracks() is used to compute long tracks (usually track_degree == 3), and Disambiguate() achieves the disambiguating purpose. They belong to the BundlerApp class.
2. "BundlerApp.h" is the class declaration file where our ComputeConstraintTracks() function (line #201) and Disambiguate() function (line #204) are declared. I only changed these two places as compared to its original version.
3. "BundlerGeometry.cpp" shows where to call our functions (lines from #56 to #61 and #90 to #96); use the new track computing function to form tracks and launch disambiguating after that.
4. "Makefile" indicates how to compile our imported codes; just add a term "Disambiguate.o"(see line #44).
Folder "script":
"RunBundler_orig.sh" is the original script to run bundler_sfm with full steps of feature selecting, matching and bundler adjustment.
In "RunBundler_skip.sh", I skip the process of feature selecting and matching (see the annotations at line #98 and #109), if you have already finished the whole bundler pipeline once, as it is so expensive to repeat them everytime.
The parameters, that I think you have to take note of, are the two in Disambiguate() function, i.e., float converage and float score_thres.
The converage controls how many iconic images will be selected. As for small-scale indoor scenes, a large value between 0.7 and 0.9 is recommended; otherwise, for large-scale unstructured datasets, the value around 0.6 would be enough.
Parameter score_thres defines whether an image pair is acceptable. As for small-scale scenes, similarly, a large threshold (around 0.3) is recommended; otherwise, for large-scale outdoor scenes, score_thres between 0.04 and 0.1 would be a good choice.
For instance, for Alexander Nevsky Cathedral dataset, we use converage = 0.6 and score_thres = 0.1 to achieve well-registered 3D point clouds.
This code is written in C++ and tested on ubuntu 16.04.
- An easy way to run our code is to directly unzip the "bundler_sfm_disambiguation.zip" file in the document and then run "RunBundler_orig.sh" or "RunBundler_skip.sh" in the directory where images are stored.
- The another way is to first download the bundler_sfm source code at https://github.com/snavely/bundler_sfm then use the files in "src" to replace its original files.
More details about bundler_sfm, please follow the manual at https://github.com/snavely/bundler_sfm.
A simple example:
cd SfM_Disambiguation/
cd bundler_sfm_disambiguation/
unzip bundler_sfm_disambiguation.zip
cd bundler_sfm_disambiguation/
make
cd examples/your_dataset_name/ (cd to the directory where your images are located)
../../Rundler_orig.sh (or ../../Rundler_skip.sh)
With respect to the datasets used in our paper, I have uploaded some of them which are small-scale and difficult to acquire at present. Please also cite these papers (Richard Roberts-CVPR11 and Nianjuan Jiang-CVPR12) when you use the datasets in your research.
Because the Temple of Haven dataset is too large, I thus could not upload it into this repository. However, you can still download it through my GoogleDrive sharing link or BaiduYun sharing link (if you can not access Google because of Firewall). But for my building dataset, I think I have lost it (it is not in my disk); It seems I forgot to backup it when graduating (I suppose I had done it...).
When you use the bundler-sfm toolkit on a new dataset, especially when the dataset is small-scale and captured from a single camera, please first check the picture EXIF information and make sure the corresponding focal knowledge is included in the "bundler_sfm/bin/extract_focal.pl" file; if not, please do remember to insert it into the file (refer to its existing terms). This would ensure you get desired outputs rather than mis-registered ones.