{"id":13818821,"url":"https://github.com/snavely/bundler_sfm","last_synced_at":"2025-05-15T23:04:05.678Z","repository":{"id":7356192,"uuid":"8680692","full_name":"snavely/bundler_sfm","owner":"snavely","description":"Bundler Structure from Motion Toolkit","archived":false,"fork":false,"pushed_at":"2019-05-13T15:27:18.000Z","size":6187,"stargazers_count":1561,"open_issues_count":39,"forks_count":483,"subscribers_count":142,"default_branch":"master","last_synced_at":"2025-05-08T12:01:55.220Z","etag":null,"topics":["3d-reconstruction","3d-vision","bundle-adjustment","computer-vision","computer-vision-tools","structure-from-motion"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snavely.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-10T04:48:37.000Z","updated_at":"2025-04-28T01:39:03.000Z","dependencies_parsed_at":"2022-08-06T20:01:11.192Z","dependency_job_id":null,"html_url":"https://github.com/snavely/bundler_sfm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snavely%2Fbundler_sfm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snavely%2Fbundler_sfm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snavely%2Fbundler_sfm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snavely%2Fbundler_sfm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snavely","download_url":"https://codeload.github.com/snavely/bundler_sfm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254436944,"owners_count":22070946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-reconstruction","3d-vision","bundle-adjustment","computer-vision","computer-vision-tools","structure-from-motion"],"created_at":"2024-08-04T08:00:31.680Z","updated_at":"2025-05-15T23:04:05.654Z","avatar_url":"https://github.com/snavely.png","language":"C","funding_links":[],"categories":["Structure from motion (SFM) software","C","SFM","OpenSource SfM (Structure from Motion)"],"sub_categories":["Project\u0026code","UAV Trajectory Optimization for model completeness"],"readme":"Bundler User's Manual\n---------------------\nwritten by Noah Snavely (snavely@cs.cornell.edu)\n\nbased on the Photo Tourism work of Noah Snavely, Steven M. Seitz, \n  (University of Washington) and Richard Szeliski (Microsoft Research)\n\nFor more information, see the Bundler homepage at \n    http://www.cs.cornell.edu/~snavely/bundler/\nor see the FAQ at \n    http://www.cs.cornell.edu/~snavely/bundler/faq.html\n\nWhat is Bundler?\n----------------\n\nBundler is a structure-from-motion system for unordered image\ncollections (for instance, images from the Internet). Bundler takes a\nset of images, image features, and image matches as input, and\nproduces a 3D reconstruction of the camera and (sparse) scene geometry\nas output. The system, described in [1] and [2], reconstructs the\nscene incrementally, a few images at a time, using a modified version\nof the Sparse Bundle Adjustment package of Lourakis and Argyros [3] as\nthe underlying optimization engine.\n\nCurrently, Bundler has been primarily compiled and tested under Linux\n(though it may also compile in Windows under Cygwin, and a Visual\nStudio solution file is also provided).\n\nConditions of use\n-----------------\n\nBundler is distributed under the GNU General Public License.  For\ninformation on commercial licensing, please contact the authors at the\ncontact address below.  If you use Bundler for a publication, please\ncite the following paper:\n\n  Noah Snavely, Steven M. Seitz, and Richard Szeliski. Photo Tourism:\n  Exploring Photo Collections in 3D. SIGGRAPH Conf. Proc., 2006.\n\nWhat's included\n---------------\n\nIncluded with the binary distribution is the Bundler executable\n(bin/bundler), as well as a number of other utility scripts and\nexecutables (in the bin/ directory). In addition, there are a number\nof example image sets (and example results) under the examples/\ndirectory. A version of the approximate nearest neighbors (ANN)\nlibrary of David M. Mount and Sunil Arya, customized for searching\nverctors of unsigned bytes, is also included.\n\nA utility program for converting bundle files (.out) to the input\nrequired by Dr. Yasutaka Furukawa's PMVS multi-view stereo system\n(http://www.di.ens.fr/pmvs/)\ncalled Bundle2PMVS is also included.  Finally, this distribution\nincludes a program called RadialUndistort for generating undistorted\nimages (based on the undistortion parameters estimated by Bundler).\n\n\nBefore you begin\n----------------\n\nYou'll first need to download the Bundler distribution from GitHub:\n\nor visit the Bundler homepage at \n\n   http://phototour.cs.washington.edu/bundler \n\nand extract it into a directory (to be referred to as BASE_PATH).\n\nYou'll also need a feature detector components to get the system\nworking. Assuming you will be using SIFT features generated by David\nLowe's SIFT binary, you'll need to download that binary from\n\n    http://www.cs.ubc.ca/~lowe/keypoints/\n\nand copy it to BASE_PATH/bin (making sure it is called 'sift', or\n'siftWin32.exe' under Windows).\n\nYou'll also need the 'jhead' program installed, for computing focal\nlengths from Exif metadata.  This is available, for instance, as the\njhead package on Ubuntu.\n\nFinally, make sure you have the ImageMagick library installed.\n\nThe utils/bundler.py script requires that you have Python and the\nPython Image Library (PIL) installed on your computer.\n\nTo make bundler, just type 'make' in the main bundler directory.\nNote that if you plan to run Bundler on large problems, you may wish\nto enable the use of the Ceres solver for bundle adjustment, which can\nimprove speed over the default SBA bundle adjuster.  To do so, edit\nthe file 'src/Makefile' and uncomment the line\n\n    USE_CERES=true\n\nNote that this assumes you have Ceres and its dependencies installed\non your system.  See the Ceres solver page at\n\n   https://code.google.com/p/ceres-solver/\n\nfor more information.\n\nFinally, once Bundler is compiled, copy the approximate nearest\nneighbors (ANN) shared library at BASE_PATH/bin/libANN_char.so\n(Linux/cygwin) or BASE_PATH/bin/ann_1.1_char.dll (Windows VS2005) to a\nlocation in your LD_LIBRARY_PATH, or add BASE_PATH/bin to\nLD_LIBRARY_PATH with a command like (in bash):\n\n    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/bundler/bin\n\n\nRunning bundler\n---------------\n\nThe easiest way to start using Bundler is to either use the provided\nRunBundler.sh bash script, or the included Python script (by Isaac\nLenton), utils/bundler.py.  Just execute either script in a directory\nwith a set of images in JPEG format, and it will automatically run all\nthe steps needed to run structure from motion on the images (assuming\neverything goes well).  For RunBundler.sh, you may optionally provide\na configuration file as a command line argument---see RunBundler.sh\nfor a description of the configuration options available.  Notably,\nyou can choose to use Ceres when running Bundler.\n\nTo get help on using the Python script bundler.py:\n\n  \u003e bundler.py -h\n\nTo run bundler.py with verbose output on a single thread (this acts\nsimilar to the older RunBundler.sh bash script):\n\n  \u003e bundler.py --verbose --no-parallel\n\nbundler.py can also be imported into your own Python modules to\nenable easy access to the bundler system.  Type 'help(bundler)'\nat the python command prompt after importing bundler.py for more\ninformation.\n\nThe Bundler exectutable is actually the last in a sequence of steps\nthat need to be run to reconstruct a scene.  bundler.py takes care\nof all these steps for you, but it's useful to know what's going on.\nThe main initial steps are to generate features and pairwise feature\nmatches for the image set.  Any type of image features can be used,\nbut Bundler assumes the features are in the SIFT format, and so David\nLowe's SIFT detector, available at\nhttp://www.cs.ubc.ca/~lowe/keypoints/, is probably the easiest to get\nworking with Bundler (bundler.py assumes that SIFT is used).  A\nlist of images containing estimating focal length information also\nmust be created.  The four steps to creating a reconstruction are\ntherefore:\n\n1. Create a list of images using the function extract_focal_length.\n   (this extracts focal length information, when available, from each\n   image, and stores it in an image list).\n2. Generate (SIFT) features for each image.\n3. Match features between each pairs of images (this step can take a\n   while).  The computed feature matches are stored in a file called\n   'matches.init.txt'.\n4. Run 'bundler' with a suitable options file.\n\nAgain, running the RunBundler.sh or bundler.py script is the easiest\nway to perform these steps.  Steps 1-3 can also be invoked\nindividually from functions contained in the bundler.py script.\n\nBundler itself is typically invoked as follows:\n\n \u003e bundler list.txt --options_file options.txt\n\nThe first argument is the list of images to be reconstructed.  Next,\nan options file containing settings to be used for the current run is\ngiven.  The RunBundler.sh and bundler.py scripts create an options\nfile that will work in many situations (and some of these options can\nbe controlled by the configuration file passed to RunBundler.sh).\nCommon options are described later in this document.  To generate only\nthe list of images, run:\n\n \u003e bundler.py --extract-focal\n\n\nOutput format\n-------------\n\nBundler produces files typically called 'bundle_*.out' (we'll call\nthese \"bundle files\").  With the default commands, Bundler outputs a\nbundle file called 'bundle_\u003cn\u003e.out' containing the current state of\nthe scene after each set of images has been registered (n = the number\nof currently registered cameras).  After all possible images have been\nregistered, Bundler outputs a final file named 'bundle.out'.  In\naddition, a \"ply\" file containing the reconstructed cameras and points\nis written after each round.  These ply files can be viewed with the\n\"scanalyze\" mesh viewer, available at\nhttp://graphics.stanford.edu/software/scanalyze/.\n\nThe bundle files contain the estimated scene and camera geometry have\nthe following format:\n\n    # Bundle file v0.3\n    \u003cnum_cameras\u003e \u003cnum_points\u003e   [two integers]\n    \u003ccamera1\u003e\n    \u003ccamera2\u003e\n     ...\n    \u003ccameraN\u003e\n    \u003cpoint1\u003e\n    \u003cpoint2\u003e\n     ...\n    \u003cpointM\u003e\n\nEach camera entry \u003ccameraI\u003e contains the estimated camera intrinsics\nand extrinsics, and has the form:\n\n    \u003cf\u003e \u003ck1\u003e \u003ck2\u003e   [the focal length, followed by two radial distortion coeffs]\n    \u003cR\u003e             [a 3x3 matrix representing the camera rotation]\n    \u003ct\u003e             [a 3-vector describing the camera translation]\n\nThe cameras are specified in the order they appear in the list of\nimages.\n\nEach point entry \u003cpointI\u003e has the form:\n\n    \u003cposition\u003e      [a 3-vector describing the 3D position of the point]\n    \u003ccolor\u003e         [a 3-vector describing the RGB color of the point]\n    \u003cview list\u003e     [a list of views the point is visible in]\n\nThe view list begins with the length of the list (i.e., the number of\ncameras the point is visible in).  The list is then given as a list of\nquadruplets \u003ccamera\u003e \u003ckey\u003e \u003cx\u003e \u003cy\u003e, where \u003ccamera\u003e is a camera index,\n\u003ckey\u003e the index of the SIFT keypoint where the point was detected in\nthat camera, and \u003cx\u003e and \u003cy\u003e are the detected positions of that\nkeypoint.  Both indices are 0-based (e.g., if camera 0 appears in the\nlist, this corresponds to the first camera in the scene file and the\nfirst image in \"list.txt\").  \n\nWe use a pinhole camera model; the parameters we estimate for each\ncamera are a focal length (f), two radial distortion parameters (k1\nand k2), a rotation (R), and translation (t), as described in the file\nspecification above.  The formula for projecting a 3D point X into a\ncamera (R, t, f) is:\n\n    P = R * X + t       (conversion from world to camera coordinates)\n    p = -P / P.z        (perspective division)\n    p' = f * r(p) * p   (conversion to pixel coordinates)\n\nwhere P.z is the third coordinate of P.  In the last equation, r(p) is\na function that computes a scaling factor to undo the radial\ndistortion:\n\n    r(p) = 1.0 + k1 * ||p||^2 + k2 * ||p||^4.\n\nThis gives a projection in pixels, where the origin of the image is\nthe center of the image, the positive x-axis points right, and the\npositive y-axis points up (in addition, in the camera coordinate\nsystem, the positive z-axis points backwards, so the camera is looking\ndown the negative z-axis, as in OpenGL).\n\nFinally, the equations above imply that the camera viewing direction\nis:\n\n    R' * [0 0 -1]'  (i.e., the third row of R or third column of R')\n\n(where ' indicates the transpose of a matrix or vector).\n\nand the 3D position of a camera is \n\n    -R' * t .\n\n\nCommand-line options\n--------------------\n\nBundler has a number of internal parameters, so there are a large\nnumber of command-line options.  That said, we've found that a common\nset of parameters works well for most image collections we've tried,\nso it is probably safe to start with the recommended options (used by\nthe RunBundler.sh and bundler.py scripts).  One very useful option is\n\"--options_file \u003cfile\u003e\", which tells Bundler to read a list of options\nfrom a file.  The default options file created by RunBundler.sh or\nbundler.py includes the following options:\n\n  --match_table matches.init.txt\n     [specifies the file where the match files are stored]\n\n  --output bundle.out\n     [specifies the name of the final output reconstruction]\n\n  --output_all bundle_\n     [specifies that all intermediate reconstructions should be\n      output to files with prefix \"bundle_\"]\n\n  --output_dir bundle\n     [the directory all output files should be written to, typically\n      called \"bundle\"]\n\n  --variable_focal_length\n     [directs bundler to optimize for an independent focal length for\n      each image]\n\n  --use_focal_estimate\n     [directs bundler to use the estimated focal lengths obtained from\n      the Exif tags for each image]\n\n  --constrain_focal\n     [constrain the focal length of each camera to be close to the\n      initial focal length estimate (from Exif tags).  This option\n      adds penalty terms to the bundle adjustment objective function]\n\n  --constrain_focal_weight 0.0001\n     [weight on the penalty terms for the focal length constraints (a\n      small weight is typically sufficient)]\n\n  --estimate_distortion\n     [directs bundler to estimate radial distortion parameters for\n      each image]\n\n  --run_bundle\n     [run structure from motion (as opposed to other operations on\n      existing reconstructions)]\n\nThere are a number of other useful options in addition to the default\nones listed above, including:\n\n  --init_pair1 \u003cimage_idx1\u003e\n  --init_pair2 \u003cimage_idx2\u003e\n     [Specifies which images to use as the initial pair.  Very useful\n      when the automatically chosen pair results in a bad\n      reconstruction.]\n\n  --options_file \u003coptions_file\u003e\n     [Read in a list of options from the specified file.]\n\n  --sift_binary \u003csift\u003e\n     [The location of the SIFT binary on your installation, e.g.,\n     '/usr/bin/sift' or '/cygdrive/c/usr/bin/siftWin32.exe'.]\n\n  --add_images \u003cadd_list\u003e\n     [Given an existing reconstruction specified with the --bundle\n      option, attempts to add the images listed in the file \u003cadd_list\u003e\n      to the reconstruction, writing the results to the file\n      'bundle.added.out'.  The new list of images is written to\n      'list.added.txt'.  Use the 'extract_focal.pl' script to generate\n      the file \u003cadd_list\u003e from a directory of JPEGs, but note that the\n      correct path to these images must be included -- which may\n      require editing the add list file.  Do not include the\n      '--run_bundle' option when adding new images.  If the SIFT key\n      files have not yet been generated for the new images, bundler\n      will try to extract features, but this requires that the\n      --sift_binary option be set.]\n\n  --help\n     [Print out the complete list of command-line options.]\n\n\nLinks\n-----\nPierre Moulon has a cmake version of Bundler available here: \n    https://github.com/TheFrenchLeaf/Bundler.\n\nAcknowledgements\n----------------\n\nThis work was supported by Microsoft Research, the University of\nWashington Animation Research Labs, an Achievement Rewards for College\nScientists (ARCS) fellowship, National Science Foundation grants\nIIS-0413198 and DGE-0203031, and an endowment by Emer Dooley and Rob\nShort.\n\nThanks to Manolis Lourakis and Antonis Argyros for their sparse bundle\nadjustment package (http://www.ics.forth.gr/~lourakis/sba/), to David\nLowe for SIFT (http://www.cs.ubc.ca/~lowe/keypoints/), to David\nM. Mount and Sunil Arya for their approximate nearest neighbors\nlibrary (http://www.cs.umd.edu/~mount/ANN/), and to Matthias Wandel\nfor his 'jhead' program.\n\nThanks as well to Kathleen Tuite and Sebastian Koch for testing this\ndistribution.\n\n\nContact information\n-------------------\n\nQuestions?  Comments?  Bug reports?  Please see the FAQ at\nhttp://www.cs.cornell.edu/~snavely/bundler/faq.html, or send email to\nNoah Snavely at snavely@cs.cornell.edu.\n\n\n[1] Noah Snavely, Steven M. Seitz, and Richard Szeliski.  Photo\n    Tourism: Exploring Photo Collections in 3D.  SIGGRAPH Conf. Proc.,\n    2006.\n\n[2] Noah Snavely, Steven M. Seitz, Richard Szeliski.  Modeling the\n    World from Internet Photo Collections. International Journal of\n    Computer Vision, 2007.\n\n[3] M.I.A. Lourakis and A.A. Argyros.  The Design and Implementation\n    of a Generic Sparse Bundle Adjustment Software Package Based on\n    the Levenberg-Marquardt Algorithm.  Tech.  Rep. 340, Inst. of\n    Computer Science-FORTH, Heraklion, Crete, Greece. Available from\n    http://www.ics.forth.gr/~lourakis/sba.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnavely%2Fbundler_sfm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnavely%2Fbundler_sfm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnavely%2Fbundler_sfm/lists"}