├── .dockerignore ├── .gitignore ├── .gitmodules ├── .travis.yml ├── .zenodo.json ├── CITATION.cff ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── NOTICE ├── README.md ├── attic └── pmpf │ ├── README.md │ ├── Server.java │ ├── example-input │ ├── pmpf │ ├── pmpf-sge-script │ └── run-slave ├── docs ├── docker.md ├── example.md ├── ideas.md ├── images │ ├── example-output.png │ ├── sfm.png │ └── sfm.svg ├── install-ubuntu-14.10.md ├── related_work.md ├── structure_from_motion.md └── tuning_guide.md ├── examples ├── rock-section │ ├── img_0001.jpg │ ├── img_0002.jpg │ ├── img_0003.jpg │ ├── img_0004.jpg │ ├── img_0005.jpg │ ├── img_0006.jpg │ ├── img_0007.jpg │ ├── img_0008.jpg │ ├── img_0009.jpg │ └── img_0010.jpg ├── rock-video │ ├── .gitignore │ └── testvideo.mp4 └── rock │ ├── .gitignore │ ├── img_0001.jpg │ ├── img_0002.jpg │ ├── img_0003.jpg │ ├── img_0004.jpg │ ├── img_0005.jpg │ ├── img_0006.jpg │ ├── img_0007.jpg │ ├── img_0008.jpg │ ├── img_0009.jpg │ ├── img_0010.jpg │ ├── img_0011.jpg │ ├── img_0012.jpg │ ├── img_0013.jpg │ ├── img_0014.jpg │ ├── img_0015.jpg │ ├── img_0016.jpg │ ├── img_0017.jpg │ ├── img_0018.jpg │ ├── img_0019.jpg │ ├── img_0020.jpg │ ├── img_0021.jpg │ ├── img_0022.jpg │ ├── img_0023.jpg │ ├── img_0024.jpg │ ├── img_0025.jpg │ ├── img_0026.jpg │ ├── img_0027.jpg │ ├── img_0028.jpg │ ├── img_0029.jpg │ ├── img_0030.jpg │ ├── img_0031.jpg │ ├── img_0032.jpg │ ├── img_0033.jpg │ ├── img_0034.jpg │ ├── img_0035.jpg │ ├── img_0036.jpg │ ├── img_0037.jpg │ ├── img_0038.jpg │ ├── img_0039.jpg │ ├── img_0040.jpg │ ├── img_0041.jpg │ ├── img_0042.jpg │ ├── img_0043.jpg │ ├── img_0044.jpg │ ├── img_0045.jpg │ ├── img_0046.jpg │ ├── img_0047.jpg │ ├── img_0048.jpg │ ├── img_0049.jpg │ ├── img_0050.jpg │ ├── img_0051.jpg │ ├── img_0052.jpg │ └── img_0053.jpg ├── image-preprocessing ├── README.md ├── cropper │ ├── README.md │ ├── crop-image-sides.sh │ └── testimage │ │ ├── 5x3-squares.jpg │ │ ├── 5x3-squares.png │ │ └── 5x3-squares.svg ├── masker │ ├── README.md │ ├── generate_mask.sh │ └── generate_mask2.sh └── resizer │ ├── README.md │ ├── resize-images.sh │ └── testimage │ ├── 5x3-squares.jpg │ ├── 5x3-squares.png │ └── 5x3-squares.svg ├── images-from-video ├── README.md ├── add-exif-data.py ├── frame-subsetter.py └── frames-extractor.py ├── run-sfm.py └── test ├── README.md ├── density.py ├── number_of_points.py ├── parse_camera_data.m ├── readcams.py ├── test_rock.py └── test_rock_section.py /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ceres-bin/ 2 | ceres-solver-1.10.0.tar.gz 3 | ceres-solver-1.10.0/ 4 | examples/SITE_*/ 5 | *.pyc 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "bundler_sfm"] 2 | path = bundler_sfm 3 | url = https://github.com/NLeSC/bundler_sfm 4 | [submodule "cmvs-pmvs"] 5 | path = cmvs-pmvs 6 | url = https://github.com/NLeSC/CMVS-PMVS 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: python 4 | 5 | services: 6 | - docker 7 | 8 | before_install: 9 | - docker pull nlesc/structure-from-motion 10 | 11 | script: 12 | - docker run -d --name test -v $TRAVIS_BUILD_DIR/examples/rock-section:/data -v $TRAVIS_BUILD_DIR/.git:/sfm/.git nlesc/structure-from-motion sleep 3000 13 | - docker exec test apt-get update 14 | - docker exec test apt-get install -y python-pip python-dev build-essential 15 | - docker exec test pip install python-coveralls 16 | - travis_wait docker exec -t test coverage run --source=/sfm /sfm/run-sfm.py 17 | - docker exec test coverage report 18 | - docker exec -e COVERALLS_REPO_TOKEN=ZtEZQsH2ivrpUHyclN37tpZE2hWREcXz6 test coveralls --base_dir=/sfm 19 | - docker exec test chown -R $UID /data 20 | - docker rm -f test 21 | - python test/test_rock_section.py $TRAVIS_BUILD_DIR/examples/rock-section 22 | -------------------------------------------------------------------------------- /.zenodo.json: -------------------------------------------------------------------------------- 1 | { 2 | "creators": [ 3 | { 4 | "affiliation": "Netherlands eScience Center", 5 | "name": "Spaaks, Jurriaan H.", 6 | "orcid": "0000-0002-7064-4069" 7 | }, 8 | { 9 | "affiliation": "Netherlands eScience Center", 10 | "name": "Drost, Niels", 11 | "orcid": "0000-0001-9795-7981" 12 | }, 13 | { 14 | "affiliation": "Netherlands eScience Center", 15 | "name": "Maassen, Jason", 16 | "orcid": "0000-0002-8172-4865" 17 | }, 18 | { 19 | "affiliation": "Netherlands eScience Center", 20 | "name": "van den Oord, Gijs" 21 | }, 22 | { 23 | "affiliation": "Netherlands eScience Center", 24 | "name": "Georgievska, Sonja" 25 | }, 26 | { 27 | "affiliation": "BIMData.io", 28 | "name": "Mor, Stéphane " 29 | }, 30 | { 31 | "affiliation": "Netherlands eScience Center", 32 | "name": "Meijer, Christiaan" 33 | }, 34 | { 35 | "affiliation": "Netherlands eScience Center", 36 | "name": "Verhoeven, Stefan", 37 | "orcid": "0000-0002-5821-2060" 38 | } 39 | ], 40 | "description": "

This is a complete Structure from Motion pipeline. Structure from Motion is a technique to construct a 3-D point cloud from a set of images (or a video) of an object. The software in this repository relies heavily on a number of third party libaries, notably Bundler, CMVS, PMVS, and SIFT.

This software is also available as a Docker image on Docker Hub, see: https://hub.docker.com/r/nlesc/structure-from-motion/.

", 41 | "keywords": [ 42 | "structure from motion", 43 | "sfm", 44 | "sift", 45 | "bundler", 46 | "CMVS", 47 | "PMVS" 48 | ], 49 | "license": { 50 | "id": "GPL-2.0" 51 | }, 52 | "title": "Structure from Motion" 53 | } 54 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # YAML 1.2 2 | --- 3 | abstract: | 4 | "

5 | This is a complete Structure from Motion pipeline. Structure from Motion is a technique to construct a 3-D point cloud from a set of images (or a video) of an object. The software in this repository relies heavily on a number of third party libaries, notably Bundler, CMVS, PMVS, and SIFT. 6 |

7 |

8 | This software is also available as a Docker image on Docker Hub, see: https://hub.docker.com/r/nlesc/structure-from-motion/. 9 |

" 10 | authors: 11 | - 12 | affiliation: "Netherlands eScience Center" 13 | family-names: Spaaks 14 | given-names: "Jurriaan H." 15 | orcid: "https://orcid.org/0000-0002-7064-4069" 16 | - 17 | affiliation: "Netherlands eScience Center" 18 | family-names: Drost 19 | given-names: Niels 20 | orcid: "https://orcid.org/0000-0001-9795-7981" 21 | - 22 | affiliation: "Netherlands eScience Center" 23 | family-names: Maassen 24 | given-names: Jason 25 | orcid: "https://orcid.org/0000-0002-8172-4865" 26 | - 27 | affiliation: "Netherlands eScience Center" 28 | family-names: Oord 29 | given-names: Gijs 30 | name-particle: "van den" 31 | - 32 | affiliation: "Netherlands eScience Center" 33 | family-names: Georgievska 34 | given-names: Sonja 35 | - 36 | affiliation: "BIMData.io" 37 | family-names: Mor 38 | given-names: "Stéphane " 39 | - 40 | affiliation: "Netherlands eScience Center" 41 | family-names: Meijer 42 | given-names: Christiaan 43 | - 44 | affiliation: "Netherlands eScience Center" 45 | family-names: Verhoeven 46 | given-names: Stefan 47 | orcid: "https://orcid.org/0000-0002-5821-2060" 48 | cff-version: "1.0.3" 49 | date-released: 2018-09-26 50 | doi: "10.5281/zenodo.594751" 51 | keywords: 52 | - "structure from motion" 53 | - sfm 54 | - sift 55 | - bundler 56 | - CMVS 57 | - PMVS 58 | license: "GPL-2.0-only" 59 | message: "If you use this software, please cite it using these metadata." 60 | repository-code: "https://github.com/NLeSC/structure-from-motion/" 61 | title: "Structure from Motion" 62 | version: "1.0.5" 63 | ... 64 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributions are welcome! Please create a pull request and adhere to the following list: 2 | 3 | 1. The code follows the standard style, check by fixing all errors 4 | 2. Use the GitHub Flow branching model 5 | 3. For other development and coding style conventions, see the NLeSC Style [Guide](https://guide.esciencecenter.nl/index.html) 6 | 4. Don't include extra dependencies without a good reason. Only use licenses compattible with the license of this project 7 | 5. Please document your code, and provide unit tests 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Docker File for structure-from-motion pipeline 2 | # Copyright 2015 Netherlands eScience Center 3 | # 4 | # 5 | # Build this image: 6 | # 7 | # sudo docker build -t sfm_image . 8 | 9 | # Run pipeline on a collection of images in the current working directory: 10 | # 11 | # sudo docker run -u $UID -v $PWD:/data sfm_image 12 | # 13 | # Alternatively, the image is also available ready-made on DockerHub: 14 | # 15 | # sudo docker run -u $UID -v $PWD:/data nlesc/structure-from-motion 16 | 17 | FROM ubuntu:16.04 18 | MAINTAINER Niels Drost 19 | 20 | # Create sfm source dir 21 | RUN mkdir /sfm 22 | 23 | # Copy sources 24 | ADD bundler_sfm /sfm/bundler_sfm 25 | ADD cmvs-pmvs /sfm/cmvs-pmvs 26 | ADD run-sfm.py /sfm/run-sfm.py 27 | 28 | # Install required packages 29 | RUN apt-get update && apt-get install -y --no-install-recommends cmake gfortran libgoogle-glog-dev libatlas-base-dev libeigen3-dev \ 30 | libsuitesparse-dev zlib1g-dev libjpeg-dev libboost-dev python-pil git build-essential wget libcholmod3.0.6 && rm -rf /var/lib/apt/lists/* \ 31 | # Download ceres 32 | && cd /opt && wget http://ceres-solver.org/ceres-solver-1.10.0.tar.gz && tar -zxf ceres-solver-1.10.0.tar.gz && rm -rf ceres-solver-1.10.0.tar.gz \ 33 | # Build ceres 34 | && cd /opt/ceres-solver-1.10.0 && mkdir build && cd build && cmake .. && make -j3 && make test && make install \ 35 | # Build bundler 36 | && cd /sfm/bundler_sfm && make \ 37 | # Build cmvs 38 | && cd /sfm/cmvs-pmvs/program && mkdir build && cd build && cmake .. && make \ 39 | # Clean up redundant packages 40 | && apt-get purge -y cmake gfortran libeigen3-dev wget build-essential && apt-get -y autoremove 41 | 42 | # Mount data volume 43 | VOLUME /data 44 | 45 | # Go to working dir 46 | WORKDIR /data 47 | 48 | # Run main script 49 | CMD /sfm/run-sfm.py 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Structure From Motion Pipeline 2 | Copyright 2015 The Netherlands eScience Center 3 | 4 | This software contains Bundler, which is copyright 2008-2013 Noah Snavely (snavely@cs.cornell.edu). See https://github.com/snavely/bundler_sfm 5 | 6 | This software contains CMVS-PMVS. See https://github.com/pmoulon/CMVS-PMVS 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Structure From Motion Pipeline 2 | ------------------------------ 3 | 4 | [![Build Status](https://travis-ci.org/NLeSC/structure-from-motion.svg?branch=develop)](https://travis-ci.org/NLeSC/structure-from-motion) 5 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/13ba2c747cde4bc4ba5809873aa40e7d)](https://www.codacy.com/app/NLeSC/structure-from-motion?utm_source=github.com&utm_medium=referral&utm_content=NLeSC/structure-from-motion&utm_campaign=Badge_Grade) 6 | [![Coverage Status](https://coveralls.io/repos/github/NLeSC/structure-from-motion/badge.svg?branch=)](https://coveralls.io/github/NLeSC/structure-from-motion?branch=) 7 | [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.45937.svg)](http://dx.doi.org/10.5281/zenodo.45937) 8 | 9 | Please cite the tool with its DOI if you are using it in your scientific publication. 10 | 11 | 12 | 13 | This repo contains a complete _Structure from Motion_ pipeline. Structure from Motion is a technique to construct a 3-D point cloud from a set of images (or a video) of an object. The software in this repository relies heavily on a number of third party libaries, notably Bundler, CMVS, PMVS, and SIFT. 14 | 15 | 16 | * Go [here](docs/install-ubuntu-14.10.md) for the installation instructions; 17 | * A conceptual overview of the pipeline is documented [here](docs/structure_from_motion.md); 18 | * The current pipeline has many options that can be configured. [This document](/docs/tuning_guide.md) describes which option does what and how it affects the characteristics of the resulting point cloud; 19 | * [This document](docs/related_work.md) lists a couple of key people, their websites, and tools; 20 | * [Here](docs/ideas.md) we describe some ideas we never found time to look into; 21 | * You can run the pipeline with [docker](https://www.docker.com/) using [this docker image](https://hub.docker.com/r/nlesc/structure-from-motion/). Find the instructions [here](docs/docker.md). 22 | 23 | 24 | 25 | 26 | Example 27 | -------- 28 | 29 | ![example-output](docs/images/example-output.png "Example Output") 30 | 31 | This software includes a small example, in this case [a rock on the parking lot outside of our building](https://www.google.com/maps/place/52%C2%B021'24.6%22N+4%C2%B057'15.1%22E/@52.356789,4.9542065,49m/data=!3m1!1e3!4m2!3m1!1s0x0:0x0). See [here](docs/example.md) for some info on how to test the pipeline on the example. 32 | 33 | 34 | 35 | 36 | Copyrights & Disclaimers 37 | ------------------------ 38 | 39 | The software is copyrighted by the Netherlands eScience Center and 40 | releases under the GNU general public license (GPL), Version 2.0. 41 | 42 | See for more information on the 43 | Netherlands eScience Center. 44 | 45 | 46 | 47 | See the "LICENSE" and "NOTICE" files for more information. 48 | 49 | -------------------------------------------------------------------------------- /attic/pmpf/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the pilot job framework file used for commiting jobs to a cluster. 2 | -------------------------------------------------------------------------------- /attic/pmpf/Server.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Netherlands eScience Center 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | import java.io.BufferedReader; 19 | import java.io.File; 20 | import java.io.FileReader; 21 | import java.io.IOException; 22 | import java.net.ServerSocket; 23 | import java.net.Socket; 24 | 25 | /** 26 | * @author Jason Maassen 27 | * @version 1.0 28 | * @since 1.0 29 | * 30 | */ 31 | public class Server { 32 | 33 | private static final short DEFAULT_PORT = 19876; 34 | 35 | private ServerSocket ss; 36 | private BufferedReader input; 37 | 38 | public Server(File inputfile, short port) throws IOException { 39 | input = new BufferedReader(new FileReader(inputfile)); 40 | ss = new ServerSocket(port, 1024); 41 | } 42 | 43 | public void run() throws IOException { 44 | 45 | boolean done = false; 46 | 47 | System.out.println("Server starting!"); 48 | 49 | while (!done) { 50 | String line = input.readLine(); 51 | 52 | if (line == null) { 53 | // We've reached EOF! 54 | input.close(); 55 | done = true; 56 | } else if (!line.startsWith("#")) { 57 | Socket tmp = ss.accept(); 58 | System.out.println("Returning line: " + line); 59 | tmp.getOutputStream().write((line+"\n").getBytes()); 60 | tmp.close(); 61 | } 62 | } 63 | 64 | System.out.println("No more input -- shutting down"); 65 | ss.close(); 66 | } 67 | 68 | public static void main(String [] args) { 69 | 70 | short port = DEFAULT_PORT; 71 | 72 | if (args.length < 1 || args.length > 2) { 73 | System.err.println("Usage nls.esciencecenter.patty.Server [port]"); 74 | System.exit(1); 75 | } 76 | 77 | File f = new File(args[0]); 78 | 79 | if (!f.exists() || !f.isFile() || !f.canRead()) { 80 | System.err.println("Cannot access inputfile " + args[0]); 81 | System.exit(1); 82 | } 83 | 84 | if (args.length == 2) { 85 | port = Short.parseShort(args[1]); 86 | } 87 | 88 | try { 89 | Server s = new Server(f, port); 90 | s.run(); 91 | } catch (Exception e) { 92 | System.err.println("Server failed: " + e.getLocalizedMessage()); 93 | e.printStackTrace(System.err); 94 | System.exit(1); 95 | } 96 | 97 | } 98 | } 99 | 100 | -------------------------------------------------------------------------------- /attic/pmpf/example-input: -------------------------------------------------------------------------------- 1 | one 2 | two 3 | three 4 | four 5 | five 6 | six 7 | seven 8 | eight 9 | nine 10 | ten 11 | eleven 12 | twelve 13 | -------------------------------------------------------------------------------- /attic/pmpf/pmpf: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #This script is in charge of starting as many workers as there are cores. 4 | 5 | for i in $(seq 1 8) 6 | do 7 | ./run-slave $@& 8 | done 9 | 10 | wait 11 | -------------------------------------------------------------------------------- /attic/pmpf/pmpf-sge-script: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #$ -S /bin/sh 3 | #$ -N patty 4 | #$ -l h_rt=24:00:00 5 | #$ -wd /var/scratch/jason/patty 6 | #$ -pe javagat 1 7 | 8 | echo "script running" 9 | 10 | cat $PE_HOSTFILE 11 | 12 | for host in `cat $PE_HOSTFILE | cut -d " " -f 1` ; do 13 | for i in {0..7} 14 | do 15 | ssh -o StrictHostKeyChecking=false $host "cd `pwd` && /var/scratch/jason/patty/code/PattyAnalytics/scripts/pmpf/run-slave"& 16 | done 17 | done 18 | 19 | wait 20 | exit 0 21 | -------------------------------------------------------------------------------- /attic/pmpf/run-slave: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HOST=fs0 4 | PORT=19876 5 | 6 | while true 7 | do 8 | #Talk to server, get next directory name 9 | DIR=`nc $HOST $PORT` 10 | 11 | #Check if netcat reported an error 12 | if [ "$?" -ne "0" ]; then 13 | echo "Failed to contact server" 14 | exit 1 15 | fi 16 | 17 | echo "GOT DIR $DIR" 18 | 19 | if [ "$DIR" = "exit" ] 20 | then 21 | #Exit is magic string send by server if we are done 22 | echo "server says we're done" 23 | exit 24 | else 25 | #Insert actual processing script call here 26 | echo "running next dir: $DIR" 27 | cd /var/scratch/jason/patty/ 28 | cp -r SITES_image_based/$DIR processed/$DIR 29 | cd processed/$DIR 30 | time /var/scratch/jason/patty/code/bundler-v0.4-source/RunBundler.sh 2>&1 >RunBundler.log 31 | fi 32 | done 33 | 34 | -------------------------------------------------------------------------------- /docs/docker.md: -------------------------------------------------------------------------------- 1 | Using Docker to run the Stucture From Motion Pipeline 2 | ===================================================== 3 | 4 | To facilitate running the pipeline with as little effort as possible we have created a docker image. 5 | 6 | Docker is a system for fast deployment of applications using virtual machines. See here for more information: https://www.docker.com/ 7 | 8 | 9 | 10 | Quick HOWTO: 11 | 12 | 1. Install Docker: ```sudo apt-get install docker.io```, 13 | 1. retrieve the docker image by running ```docker pull nlesc/structure-from-motion```, 14 | 1. go to the examples directory 'examples/rock', 15 | 1. start the image using ```sudo docker run -u $UID -v "$PWD:/data" nlesc/structure-from-motion```. To process your own set of images, run this command inside the directory containing your image files. 16 | 17 | By default the docker image will run the entire structure-from-motion pipeline on all pictures in the current working directory. If instead you would like a terminal session to play around with the image try this command: 18 | ```` 19 | sudo docker run -u $UID -v "$PWD:/data" -i -t nlesc/structure-from-motion /bin/bash 20 | ```` 21 | The main script to run the pipeline is called run-sfm.py'. 22 | The image can also be built from source. To do this yourself, you need to checkout the submodules: 23 | ```` 24 | git submodule update --init --recursive 25 | ```` 26 | Then, build the image using the Dockerfile in the repository root directory: 27 | ```` 28 | sudo docker build -t sfm_image . 29 | sudo docker run -u $UID -v $PWD:/data sfm_image 30 | ```` 31 | -------------------------------------------------------------------------------- /docs/example.md: -------------------------------------------------------------------------------- 1 | The example folder (examples/rock) contains an example input for the pipeline, in this case a rock. 2 | 3 | After [installing](install-ubuntu-14.10.md), the pipeline can be started by cd'ing into the data directory, and starting the 'run-sfm.py' script from there: 4 | 5 | ``` 6 | $ cd ${HOME}/structure-from-motion/examples/rock 7 | $ python ../../run-sfm.py 8 | ``` 9 | 10 | Alternatively, the docker image can be used, see [here](docker.md). 11 | 12 | ``` 13 | $ cd examples/rock 14 | $ sudo docker run -u $UID -v $PWD:/data nlesc/structure-from-motion 15 | ``` 16 | 17 | Viewing the resulting sparse pointcloud (in bundle/bundle.out) and dense pointcloud (in pmvs/models/optio-0000.ply) with for example [meshlab](http://meshlab.sourceforge.net/). 18 | 19 | To test if the point cloud was correctly generated, you can use a test script which prints the number of points in the generated cloud: 20 | 21 | ``` 22 | $ cd ${HOME}/structure-from-motion 23 | $ test/number_of_points.py examples/rock 24 | 25 | # Using 'bundle.out' file from here: examples/rock/bundle/bundle.out 26 | # Using 'option-0000.ply' from here: examples/rock/pmvs/models/option-0000.ply 27 | # The results are: 28 | # nPointsSparse = 9753 29 | # nPointsDense = 2497111 30 | 31 | 9753 32 | 2497111 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/ideas.md: -------------------------------------------------------------------------------- 1 | This document collects some of the ideas that we never had time to look into. 2 | 3 | Here's the list: 4 | * [Brute force calculation of point clouds](#brute-force-calculation-of-point-clouds) 5 | * [Quick feedback system](#quick-feedback-system) 6 | * [Camera parameters sensitivity analysis](#camera-parameters-sensitivity-analysis) 7 | * Improve visual quality of objects 8 | * [Alternative keypoint detectors](#alternative-keypoint-detectors) 9 | * [Improve accuracy of key matching by adding easily identifiable objects](#improve-accuracy-of-key-matching-by-adding-easily-identifiable-objects) 10 | 11 |