├── LICENSE ├── README.md ├── __init__.py ├── bundle_adjustment.py ├── datasets ├── Viking │ ├── 00.jpg │ ├── 01.jpg │ ├── 02.jpg │ ├── 03.jpg │ ├── 04.jpg │ ├── 05.jpg │ ├── 06.jpg │ ├── 07.jpg │ ├── 08.jpg │ ├── 09.jpg │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 22.jpg │ ├── 23.jpg │ ├── 24.jpg │ ├── 25.jpg │ ├── 26.jpg │ ├── 27.jpg │ ├── 28.jpg │ ├── 29.jpg │ ├── 30.jpg │ ├── 31.jpg │ ├── 32.jpg │ ├── 33.jpg │ ├── 34.jpg │ ├── 35.jpg │ ├── 36.jpg │ ├── 37.jpg │ ├── 38.jpg │ ├── 39.jpg │ ├── 40.jpg │ ├── 41.jpg │ ├── 42.jpg │ ├── 43.jpg │ ├── 44.jpg │ ├── 45.jpg │ ├── 46.jpg │ ├── 47.jpg │ └── 48.jpg └── templeRing │ ├── 00.png │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ ├── 06.png │ ├── 07.png │ ├── 08.png │ ├── 09.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 17.png │ ├── 18.png │ ├── 19.png │ ├── 20.png │ ├── 21.png │ ├── 22.png │ ├── 23.png │ ├── 24.png │ ├── 25.png │ ├── 26.png │ ├── 27.png │ ├── 28.png │ ├── 29.png │ ├── 30.png │ ├── 31.png │ ├── 32.png │ ├── 33.png │ ├── 34.png │ ├── 35.png │ ├── 36.png │ ├── 37.png │ ├── 38.png │ ├── 39.png │ ├── 40.png │ ├── 41.png │ ├── 42.png │ ├── 43.png │ ├── 44.png │ ├── 45.png │ ├── README.txt │ ├── templeR_ang.txt │ └── templeR_par.txt ├── environment.yml ├── main.ipynb ├── matching.py ├── reconstruction.py └── results └── results_collage.png /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # An implementation of incremental Structure from Motion 2 | 3 | Structure from motion is an algorithm that generates a 3D reconstruction (pointcloud) from a sequence of 2D images. Instructions on running the repo can be found below. The rough steps of my pipeline are: 4 | 5 | **i)** Match keypoints between images 6 | **ii)** Find a good image pair to initialize the reconstruction (many matches and significant rotation between images) 7 | **iii)** Extend the reconstruction by resecting adjacent images with PnP and triangulating new points 8 | **iv)** Refine camera parameters and 3D point coordinates with bundle adjustment regularly 9 | 10 | Here are examples of the output I was able to generate: 11 | 12 | ![](results/results_collage.png) 13 | 14 | Note: temple image set obtained from: http://vision.middlebury.edu/mview/data/. Viking image set was created by me. 15 | 16 | Main requirements for repo: cv2, numpy, scipy, pyntcloud, random 17 | 18 | If desired, clone this repository and setup the conda environment: 19 | ``` 20 | git clone https://github.com/rshilliday/sfm.git 21 | cd sfm 22 | conda env create -n sfm -f environment.yml 23 | conda activate sfm 24 | ``` 25 | 26 | Now, run jupyter: 27 | ``` 28 | jupyter notebook 29 | ``` 30 | Open main.ipynb and hit "run all" to generate a 3D reconstruction of the "templeRing" dataset. 31 | 32 | To generate a reconstruction of the Viking dataset, in the second cell of main.ipynb change n_imgs to 49 and change the imgset parameter of `find_features()` to 'Viking', and then hit "run all". 33 | 34 | If you would like to run this code on another dataset, you're welcome to do so, and the changes you'll need to make are as follows: 35 | 36 | 1. Go to the `find_features()` function in matching.py 37 | 2. After the `elif imgset == 'Viking:` conditional block, add the following: 38 | ``` 39 | elif imgset == '': 40 | img = cv2.imread(f'./datasets//{i:02d}.', cv2.IMREAD_GRAYSCALE) 41 | K = # You will have to proivde an intrinsics matrix here 42 | ``` 43 | 3. Put your folder of images in the datasets folder 44 | 4. Then in the 2nd cell of main.ipynb, change n_imgs to however many images are in your dataset, and change the imgset parameter in `find_features` to the name of your image set, then hit run all 45 | 46 | Please note that my implementation assumes that all images are the same size, are taken in a ring around the object you want to reconstruct and are named from 00.jpg (or .png etc) to n_imgs.jpg (up to 99.jpg max). So for example, the Viking images range from 00.jpg to 48.jpg where all consecutive images are adjacent and 00 and 48 are also adjacent. 47 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/__init__.py -------------------------------------------------------------------------------- /bundle_adjustment.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | from scipy.optimize import least_squares 4 | from scipy.sparse import lil_matrix 5 | 6 | def bundle_adjustment_sparsity(n_cameras, n_points, camera_indices, point_indices): 7 | """ 8 | 9 | :param n_cameras Integer. Number of cameras/images currently resected 10 | :param n_points: number of distinct 3D points that have been triangulated 11 | :param camera_indices: List. Value at ith position is index of camera that sees ith 2D point 12 | :param point_indices: List. Value at ith position is index of 3D point that sees ith 2D point 13 | """ 14 | m = camera_indices.size * 2 15 | n = n_cameras * 12 + n_points * 3 16 | A = lil_matrix((m, n), dtype=int) 17 | 18 | i = np.arange(camera_indices.size) 19 | for s in range(12): 20 | A[2 * i, camera_indices * 12 + s] = 1 21 | A[2 * i + 1, camera_indices * 12 + s] = 1 22 | 23 | for s in range(3): 24 | A[2 * i, n_cameras * 12 + point_indices * 3 + s] = 1 25 | A[2 * i + 1, n_cameras * 12 + point_indices * 3 + s] = 1 26 | 27 | return A 28 | 29 | def project(points, camera_params, K): 30 | """ 31 | Projects 3D points onto camera coordinates 32 | 33 | :param points: N x 3 List of 3D point coordinates 34 | :param camera_params: N x 12 List of 12D camera parameters (r1, ... r9, t1, t2, t3) 35 | :param K: Intrinsics matrix 36 | """ 37 | points_proj = [] 38 | 39 | for idx in range(len(camera_params)): # idx applies to both points and cam_params, they are = length vectors 40 | R = camera_params[idx][:9].reshape(3,3) 41 | rvec, _ = cv2.Rodrigues(R) 42 | t = camera_params[idx][9:] 43 | pt = points[idx] 44 | pt = np.expand_dims(pt, axis=0) 45 | pt, _ = cv2.projectPoints(pt, rvec, t, K, distCoeffs=np.array([])) 46 | pt = np.squeeze(np.array(pt)) 47 | points_proj.append(pt) 48 | 49 | return points_proj 50 | 51 | def fun(params, n_cameras, n_points, camera_indices, point_indices, points_2d, K): 52 | """Compute residuals (ie reprojection error) for Bundle Adjustment. 53 | 54 | :param params: List of all parameters. First n_cameras*12 parameters are (r1, ..., r9, t1, t2, t3) 55 | for each resected camera. Remaining n_points*3 paramaters are (x, y, z) coord of each triangulated point 56 | :param n_cameras: Integer. # of resected cameras 57 | :param n_points: Integer. # of triangulated points 58 | :param camera_indices: List of indices of cameras viewing each 2D observation 59 | :param point_indices: List of indices of 3D points corresponding to each 2D observation 60 | :points_2d: 2D pixel coordinates of each observation by a camera of a 3D point 61 | :param K: Intrinsics matrix 62 | """ 63 | camera_params = params[:n_cameras * 12].reshape((n_cameras, 12)) 64 | points_3d = params[n_cameras * 12:].reshape((n_points, 3)) 65 | points_proj = project(points_3d[point_indices], camera_params[camera_indices], K) 66 | return (points_proj - points_2d).ravel() 67 | 68 | def do_BA(points3d_with_views, R_mats, t_vecs, resected_imgs, keypoints, K, ftol): 69 | """ 70 | Perform Bundle Adjustment on all currently resected images and all triangulated 3D points. Return updated 71 | values for camera poses and 3D point coordinates. 72 | 73 | :param points3d_with_views: List of Point3D_with_views objects. 74 | :param R_mats: Dict mapping index of resected cameras to their Rotation matrix 75 | :param t_vecs: Dict mapping index of resected cameras to their translation vector 76 | :param resected_imgs: List of indices of resected images 77 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 78 | :param ftol: Tolerance for change in total reprojection error. Used so scipy.optimize.least_squares knows 79 | when to stop adjusting 80 | """ 81 | point_indices = [] 82 | points_2d = [] 83 | camera_indices = [] 84 | points_3d = [] 85 | camera_params = [] 86 | BA_cam_idxs = {} # maps from true cam indices to 'normalized' (i.e 11, 23, 31 maps to -> 0, 1, 2) 87 | cam_count = 0 88 | 89 | for r in resected_imgs: 90 | BA_cam_idxs[r] = cam_count 91 | camera_params.append(np.hstack((R_mats[r].ravel(), t_vecs[r].ravel()))) 92 | cam_count += 1 93 | 94 | for pt3d_idx in range(len(points3d_with_views)): 95 | points_3d.append(points3d_with_views[pt3d_idx].point3d) 96 | for cam_idx, kpt_idx in points3d_with_views[pt3d_idx].source_2dpt_idxs.items(): 97 | if cam_idx not in resected_imgs: continue 98 | point_indices.append(pt3d_idx) 99 | camera_indices.append(BA_cam_idxs[cam_idx])#append normalized cam idx 100 | points_2d.append(keypoints[cam_idx][kpt_idx].pt) 101 | if len(points_3d[0]) == 3: points_3d = np.expand_dims(points_3d, axis=0) 102 | 103 | point_indices = np.array(point_indices) 104 | points_2d = np.array(points_2d) 105 | camera_indices = np.array(camera_indices) 106 | points_3d = np.squeeze(points_3d) 107 | camera_params = np.array(camera_params) 108 | 109 | n_cameras = camera_params.shape[0] 110 | n_points = points_3d.shape[0] 111 | x0 = np.hstack((camera_params.ravel(), points_3d.ravel())) 112 | A = bundle_adjustment_sparsity(n_cameras, n_points, camera_indices, point_indices) 113 | 114 | res = least_squares(fun, x0, jac_sparsity=A, verbose=2, x_scale='jac', loss='linear', ftol=ftol, xtol=1e-12, method='trf', 115 | args=(n_cameras, n_points, camera_indices, point_indices, points_2d, K)) 116 | 117 | adjusted_camera_params = res.x[:n_cameras * 12].reshape(n_cameras, 12) 118 | adjusted_points_3d = res.x[n_cameras * 12:].reshape(n_points, 3) 119 | adjusted_R_mats = {} 120 | adjusted_t_vecs = {} 121 | for true_idx, norm_idx in BA_cam_idxs.items(): 122 | adjusted_R_mats[true_idx] = adjusted_camera_params[norm_idx][:9].reshape(3,3) 123 | adjusted_t_vecs[true_idx] = adjusted_camera_params[norm_idx][9:].reshape(3,1) 124 | R_mats = adjusted_R_mats 125 | t_vecs = adjusted_t_vecs 126 | for pt3d_idx in range(len(points3d_with_views)): 127 | points3d_with_views[pt3d_idx].point3d = np.expand_dims(adjusted_points_3d[pt3d_idx], axis=0) 128 | 129 | return points3d_with_views, R_mats, t_vecs 130 | -------------------------------------------------------------------------------- /datasets/Viking/00.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/00.jpg -------------------------------------------------------------------------------- /datasets/Viking/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/01.jpg -------------------------------------------------------------------------------- /datasets/Viking/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/02.jpg -------------------------------------------------------------------------------- /datasets/Viking/03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/03.jpg -------------------------------------------------------------------------------- /datasets/Viking/04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/04.jpg -------------------------------------------------------------------------------- /datasets/Viking/05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/05.jpg -------------------------------------------------------------------------------- /datasets/Viking/06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/06.jpg -------------------------------------------------------------------------------- /datasets/Viking/07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/07.jpg -------------------------------------------------------------------------------- /datasets/Viking/08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/08.jpg -------------------------------------------------------------------------------- /datasets/Viking/09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/09.jpg -------------------------------------------------------------------------------- /datasets/Viking/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/10.jpg -------------------------------------------------------------------------------- /datasets/Viking/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/11.jpg -------------------------------------------------------------------------------- /datasets/Viking/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/12.jpg -------------------------------------------------------------------------------- /datasets/Viking/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/13.jpg -------------------------------------------------------------------------------- /datasets/Viking/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/14.jpg -------------------------------------------------------------------------------- /datasets/Viking/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/15.jpg -------------------------------------------------------------------------------- /datasets/Viking/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/16.jpg -------------------------------------------------------------------------------- /datasets/Viking/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/17.jpg -------------------------------------------------------------------------------- /datasets/Viking/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/18.jpg -------------------------------------------------------------------------------- /datasets/Viking/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/19.jpg -------------------------------------------------------------------------------- /datasets/Viking/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/20.jpg -------------------------------------------------------------------------------- /datasets/Viking/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/21.jpg -------------------------------------------------------------------------------- /datasets/Viking/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/22.jpg -------------------------------------------------------------------------------- /datasets/Viking/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/23.jpg -------------------------------------------------------------------------------- /datasets/Viking/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/24.jpg -------------------------------------------------------------------------------- /datasets/Viking/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/25.jpg -------------------------------------------------------------------------------- /datasets/Viking/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/26.jpg -------------------------------------------------------------------------------- /datasets/Viking/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/27.jpg -------------------------------------------------------------------------------- /datasets/Viking/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/28.jpg -------------------------------------------------------------------------------- /datasets/Viking/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/29.jpg -------------------------------------------------------------------------------- /datasets/Viking/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/30.jpg -------------------------------------------------------------------------------- /datasets/Viking/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/31.jpg -------------------------------------------------------------------------------- /datasets/Viking/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/32.jpg -------------------------------------------------------------------------------- /datasets/Viking/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/33.jpg -------------------------------------------------------------------------------- /datasets/Viking/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/34.jpg -------------------------------------------------------------------------------- /datasets/Viking/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/35.jpg -------------------------------------------------------------------------------- /datasets/Viking/36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/36.jpg -------------------------------------------------------------------------------- /datasets/Viking/37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/37.jpg -------------------------------------------------------------------------------- /datasets/Viking/38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/38.jpg -------------------------------------------------------------------------------- /datasets/Viking/39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/39.jpg -------------------------------------------------------------------------------- /datasets/Viking/40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/40.jpg -------------------------------------------------------------------------------- /datasets/Viking/41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/41.jpg -------------------------------------------------------------------------------- /datasets/Viking/42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/42.jpg -------------------------------------------------------------------------------- /datasets/Viking/43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/43.jpg -------------------------------------------------------------------------------- /datasets/Viking/44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/44.jpg -------------------------------------------------------------------------------- /datasets/Viking/45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/45.jpg -------------------------------------------------------------------------------- /datasets/Viking/46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/46.jpg -------------------------------------------------------------------------------- /datasets/Viking/47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/47.jpg -------------------------------------------------------------------------------- /datasets/Viking/48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/Viking/48.jpg -------------------------------------------------------------------------------- /datasets/templeRing/00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/00.png -------------------------------------------------------------------------------- /datasets/templeRing/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/01.png -------------------------------------------------------------------------------- /datasets/templeRing/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/02.png -------------------------------------------------------------------------------- /datasets/templeRing/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/03.png -------------------------------------------------------------------------------- /datasets/templeRing/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/04.png -------------------------------------------------------------------------------- /datasets/templeRing/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/05.png -------------------------------------------------------------------------------- /datasets/templeRing/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/06.png -------------------------------------------------------------------------------- /datasets/templeRing/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/07.png -------------------------------------------------------------------------------- /datasets/templeRing/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/08.png -------------------------------------------------------------------------------- /datasets/templeRing/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/09.png -------------------------------------------------------------------------------- /datasets/templeRing/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/10.png -------------------------------------------------------------------------------- /datasets/templeRing/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/11.png -------------------------------------------------------------------------------- /datasets/templeRing/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/12.png -------------------------------------------------------------------------------- /datasets/templeRing/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/13.png -------------------------------------------------------------------------------- /datasets/templeRing/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/14.png -------------------------------------------------------------------------------- /datasets/templeRing/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/15.png -------------------------------------------------------------------------------- /datasets/templeRing/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/16.png -------------------------------------------------------------------------------- /datasets/templeRing/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/17.png -------------------------------------------------------------------------------- /datasets/templeRing/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/18.png -------------------------------------------------------------------------------- /datasets/templeRing/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/19.png -------------------------------------------------------------------------------- /datasets/templeRing/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/20.png -------------------------------------------------------------------------------- /datasets/templeRing/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/21.png -------------------------------------------------------------------------------- /datasets/templeRing/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/22.png -------------------------------------------------------------------------------- /datasets/templeRing/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/23.png -------------------------------------------------------------------------------- /datasets/templeRing/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/24.png -------------------------------------------------------------------------------- /datasets/templeRing/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/25.png -------------------------------------------------------------------------------- /datasets/templeRing/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/26.png -------------------------------------------------------------------------------- /datasets/templeRing/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/27.png -------------------------------------------------------------------------------- /datasets/templeRing/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/28.png -------------------------------------------------------------------------------- /datasets/templeRing/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/29.png -------------------------------------------------------------------------------- /datasets/templeRing/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/30.png -------------------------------------------------------------------------------- /datasets/templeRing/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/31.png -------------------------------------------------------------------------------- /datasets/templeRing/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/32.png -------------------------------------------------------------------------------- /datasets/templeRing/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/33.png -------------------------------------------------------------------------------- /datasets/templeRing/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/34.png -------------------------------------------------------------------------------- /datasets/templeRing/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/35.png -------------------------------------------------------------------------------- /datasets/templeRing/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/36.png -------------------------------------------------------------------------------- /datasets/templeRing/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/37.png -------------------------------------------------------------------------------- /datasets/templeRing/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/38.png -------------------------------------------------------------------------------- /datasets/templeRing/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/39.png -------------------------------------------------------------------------------- /datasets/templeRing/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/40.png -------------------------------------------------------------------------------- /datasets/templeRing/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/41.png -------------------------------------------------------------------------------- /datasets/templeRing/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/42.png -------------------------------------------------------------------------------- /datasets/templeRing/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/43.png -------------------------------------------------------------------------------- /datasets/templeRing/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/44.png -------------------------------------------------------------------------------- /datasets/templeRing/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/datasets/templeRing/45.png -------------------------------------------------------------------------------- /datasets/templeRing/README.txt: -------------------------------------------------------------------------------- 1 | templeRing data set -- 47 views sampled on a ring 2 | 3 | The object is a plaster replica of "Temple of the Dioskouroi" in Agrigento (Sicily) 4 | 5 | The (tight) bounding box for the templeRing model is 6 | (-0.023121 -0.038009 -0.091940) 7 | (0.078626 0.121636 -0.017395) 8 | 9 | -------------------------- 10 | Created by Steve Seitz, James Diebel, Daniel Scharstein, Brian Curless, and Rick Szeliski 11 | 12 | This directory contains images with camera calibration parameters. 13 | 14 | The images were captured using the Stanford spherical light field gantry, and calibrated by the above people. 15 | 16 | *.png: images in png format 17 | *_par.txt: camera parameters. There is one line for each image. The format for each line is: 18 | "imgname.png k11 k12 k13 k21 k22 k23 k31 k32 k33 r11 r12 r13 r21 r22 r23 r31 r32 r33 t1 t2 t3" 19 | The projection matrix for that image is given by K*[R t] 20 | The image origin is top-left, with x increasing horizontally, y vertically 21 | *_ang.txt: latitude, longitude angles for each image. Not needed to compute scene->image mapping, but may be helpful for visualization. 22 | 23 | Note that (lat, lon) corresponds to the same image as (-lat, 180 + lon), rotated 180 degrees in the image plane. While it would therefore be sufficient in principle to capture only positive latitude images, in practice some images are not useable because of shadows where the gantry occludes the light source. Because the gantry is in a different configuration for positive vs. negative latitude images, this gives us two chances to capture each viewpoint without shadows. It is for this reason that some images may have positive and others negative latitudes. This also explains why some images may appear to be "upside-down" (in fact they're rotated 180 degrees). 24 | -------------------------------------------------------------------------------- /datasets/templeRing/templeR_ang.txt: -------------------------------------------------------------------------------- 1 | -82.173913 -180.0 templeR0001.png 2 | -82.173913 -172.340426 templeR0002.png 3 | -82.173913 -164.680851 templeR0003.png 4 | -82.173913 -157.021277 templeR0004.png 5 | -82.173913 -149.361702 templeR0005.png 6 | -82.173913 -103.404255 templeR0006.png 7 | -82.173913 -95.744681 templeR0007.png 8 | -82.173913 -88.085106 templeR0008.png 9 | -82.173913 -80.425532 templeR0009.png 10 | -82.173913 -72.765957 templeR0010.png 11 | -82.173913 -65.106383 templeR0011.png 12 | -82.173913 -57.446809 templeR0012.png 13 | -82.173913 49.787234 templeR0013.png 14 | -82.173913 57.446809 templeR0014.png 15 | -82.173913 65.106383 templeR0015.png 16 | -82.173913 72.765957 templeR0016.png 17 | -82.173913 80.425532 templeR0017.png 18 | -82.173913 88.085106 templeR0018.png 19 | -82.173913 95.744681 templeR0019.png 20 | -82.173913 103.404255 templeR0020.png 21 | -82.173913 111.06383 templeR0021.png 22 | -82.173913 118.723404 templeR0022.png 23 | -82.173913 126.382979 templeR0023.png 24 | -82.173913 134.042553 templeR0024.png 25 | -82.173913 141.702128 templeR0025.png 26 | -82.173913 149.361702 templeR0026.png 27 | -82.173913 157.021277 templeR0027.png 28 | -82.173913 164.680851 templeR0028.png 29 | -82.173913 172.340426 templeR0029.png 30 | -82.173913 180.0 templeR0030.png 31 | -82.173913 185.0 templeR0031.png 32 | 82.173913 185.0 templeR0032.png 33 | 82.173913 180.0 templeR0033.png 34 | 82.173913 172.340426 templeR0034.png 35 | 82.173913 164.680851 templeR0035.png 36 | 82.173913 157.021277 templeR0036.png 37 | 82.173913 149.361702 templeR0037.png 38 | 82.173913 141.702128 templeR0038.png 39 | 82.173913 134.042553 templeR0039.png 40 | 82.173913 72.765957 templeR0040.png 41 | 82.173913 65.106383 templeR0041.png 42 | 82.173913 -134.042553 templeR0042.png 43 | 82.173913 -141.702128 templeR0043.png 44 | 82.173913 -149.361702 templeR0044.png 45 | 82.173913 -157.021277 templeR0045.png 46 | 82.173913 -164.680851 templeR0046.png 47 | 82.173913 -172.340426 templeR0047.png 48 | -------------------------------------------------------------------------------- /datasets/templeRing/templeR_par.txt: -------------------------------------------------------------------------------- 1 | 47 2 | templeR0001.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.02187598221295043000 0.98329680886213122000 -0.18068986436368856000 0.99856708067455469000 -0.01266114646423925600 0.05199500709979997700 0.04883878372068499500 -0.18156839221560722000 -0.98216479887691122000 -0.0292149526928 -0.0241923869131 0.52269561933 3 | templeR0002.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.00272557078828676410 0.98353557606148900000 -0.18069405603193772000 0.99651741905514424000 -0.01773058775937118300 -0.08147797111723514800 -0.08334029507718225500 -0.17984270037758626000 -0.98015865977776562000 -0.0288222339759 -0.0306361018019 0.525505113107 4 | templeR0003.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.01625331773280620100 0.98386957700862299000 -0.17814736905031653000 0.97668439268305030000 -0.02252259937820530100 -0.21349550254417543000 -0.21406407160478280000 -0.17746376518636725000 -0.96056399333613396000 -0.0283090812583 -0.0366442193256 0.529139415773 5 | templeR0004.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.03472199972816788400 0.98429285136236500000 -0.17309524976677537000 0.93942192751145170000 -0.02695166652093134900 -0.34170169707277304000 -0.34099974317519038000 -0.17447403941185566000 -0.92373047190496216000 -0.0276846518951 -0.0421095229316 0.533533672172 6 | templeR0005.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.05235090589954815400 0.98479784589115438000 -0.16562785206491965000 0.88539496349116698000 -0.03093875352325572600 -0.46380874523331522000 -0.46188217250287084000 -0.17092687400923678000 -0.87031538103463302000 -0.0269600886818 -0.0469344855587 0.53860946783 7 | templeR0006.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.12459423323539082000 0.98895928871004091000 -0.08022345242268591500 0.28153512590579682000 -0.04229297064421112100 -0.95861842122676455000 -0.95142748011905343000 -0.14202404693648824000 -0.27315731761402628000 -0.0213278189953 -0.0585886486063 0.577671141223 8 | templeR0007.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.12902889964175443000 0.98972522526380413000 -0.06160780416270468500 0.15113946088460242000 -0.04177353409104934300 -0.98762940175607139000 -0.98005530783764949000 -0.13674410526986550000 -0.14419654383234767000 -0.0203322512475 -0.0573229419388 0.584525028903 9 | templeR0008.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.13094087941651120000 0.99047594118902094000 -0.04256637197781731200 0.01804620524972981900 -0.04054762015799551900 -0.99901462700783672000 -0.99122591802964632000 -0.13158001529581215000 -0.01256499108788178600 -0.0193677533749 -0.0551454095765 0.591150514125 10 | templeR0009.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.13029605274095349000 0.99119803974812748000 -0.02343895559951655200 -0.11536955428847780000 -0.03863710562518051000 -0.99257092442413708000 -0.98473996800343433000 -0.12662393165740077000 0.11938833840965069000 -0.0184515371141 -0.052094910199 0.597429363235 11 | templeR0010.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.12710592639585813000 0.99187863526170994000 -0.00456687928660556850 -0.24672704479464908000 -0.03607608317631801800 -0.96841328036616370000 -0.96071319801590616000 -0.12196429450467509000 0.24930876844593125000 -0.0175999521295 -0.0482258792521 0.603249531644 12 | templeR0011.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.12142742908621770000 0.99250558231074071000 0.01371307943275649300 -0.37368215477705607000 -0.03291025497981744900 -0.92697279481025718000 -0.91957437255867858000 -0.11768425637773697000 0.37487783227890548000 -0.0168281951954 -0.0436073606852 0.608507156804 13 | templeR0012.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.11336189346759781000 0.99306769310348053000 0.03107471678989884300 -0.49396938490232206000 -0.02919611501518744300 -0.86898897210910642000 -0.86205761285929272000 -0.11386019401947006000 0.49385476440871356000 -0.0161500382152 -0.0383217716083 0.613108417072 14 | templeR0013.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.11541167827420966000 0.99138900083137627000 0.06187078105613172400 -0.68405289691836879000 0.03416081723372646500 0.72863205583031487000 0.72024424935956100000 -0.12641553542381334000 0.68210507523987296000 -0.0193474918165 0.04321050765 0.589790751867 15 | templeR0014.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.12777196254899612000 0.99067700959105598000 0.04725873733079036200 -0.58073706790091917000 0.03610343749372974000 0.81329023095508723000 0.80400173106295025000 -0.13136058948124074000 0.57993586885009962000 -0.020311130356 0.0452044463785 0.583107596409 16 | templeR0015.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.13807231488914926000 0.98993281310425651000 0.03112975105337044400 -0.46705847237686349000 0.03736281839816532600 0.88343670015589459000 0.87337988254947896000 -0.13651756422101491000 0.46751527827122269000 -0.0213062156734 0.0462806066905 0.576221332616 17 | templeR0016.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.14612892702451932000 0.98916969148300282000 0.01377164253398251200 -0.34504569459932793000 0.03791648656454157900 0.93781971011760457000 0.92714066102459869000 -0.14179443394584298000 0.34684943877257168000 -0.022314990573 0.046419784801 0.569254845159 18 | templeR0017.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.15179802911763335000 0.98840126254897120000 -0.00450583483961328880 -0.21687603817600701000 0.03775456170465282800 0.97546879864789560000 0.96432470798019132000 -0.14709703349180536000 0.22009161800675056000 -0.023319453575 0.0456194969081 0.56233245026 19 | templeR0018.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.15497845444162242000 0.98764123913336677000 -0.02337651432514656000 -0.08483672679970129200 0.03687993341332458700 0.99571210713606428000 0.98426846360370535000 -0.15233073647342665000 0.08950384506078289100 -0.0243016797537 0.0438940243752 0.555577680012 20 | templeR0019.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.15561344905257055000 0.98690318367577234000 -0.04250365307344607100 0.04871602898881084000 0.03530820922726550500 0.99818839849034746000 0.98661603625398486000 -0.15740214868860103000 -0.04258357188737407100 -0.0252441415132 0.0412741578549 0.549111071704 21 | templeR0020.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.15369168129242777000 0.98620026698413343000 -0.06154592189520560800 0.18139894256925762000 0.03306743700817096200 0.98285348259263228000 0.97132553283451883000 -0.16222076935502000000 -0.17381349560262413000 -0.0261300203575 0.0378066496047 0.543048023786 22 | templeR0021.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.14924744465611009000 0.98554503244193847000 -0.08016351596979645600 0.31084431847048910000 0.03019760281070211000 0.94998100742020297000 0.93866980879233486000 -0.16670061131713207000 -0.30184415887715305000 -0.0269435079864 0.033553376496 0.537496729928 23 | templeR0022.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.14236004780071046000 0.98494917289452277000 -0.09802419907642616300 0.43474216742556909000 0.02674991963607963000 0.90015759157026587000 0.88923161473954448000 -0.17076173053075644000 -0.42439081839012904000 -0.0276700874835 0.0285902393879 0.532556254534 24 | templeR0023.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.13315239470762694000 0.98442332131574717000 -0.11480925151440334000 0.55088156138098920000 0.02278591058187676500 0.83427232221223668000 0.82389316365295051000 -0.17433165727608951000 -0.53926665774670712000 -0.0282967932082 0.0230058042978 0.528314759229 25 | templeR0024.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.12178879854502510000 0.98397686167544829000 -0.13021913928564777000 0.65718996007304553000 0.01837631450844677200 0.75350094057292005000 0.74382043863297265000 -0.17734668520280353000 -0.64442168517161924000 -0.02881244142 0.0168997270462 0.524847934694 26 | templeR0025.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.10847204002101654000 0.98361776094118725000 -0.14397887655737707000 0.75177031506244740000 0.01359981962341879100 0.65928479301218457000 0.65044231867598168000 -0.17975301184474191000 -0.73797943386530540000 -0.0292078304973 0.0103809691492 0.522217645599 27 | templeR0026.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.09343976044991392200 0.98335242736691753000 -0.15584291693450159000 0.83293481322054796000 0.00854166382610888240 0.55330519327431971000 0.54542516268715846000 -0.18150769562383026000 -0.81827033939708060000 -0.0294759046107 0.00356585968151 0.520470830197 28 | templeR0027.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.07696020733473872600 0.98318559576803610000 -0.16559954939928406000 0.89923509311540939000 0.00329210872029469690 0.43745332245840185000 0.43064297718262490000 -0.18257942461960402000 -0.88386162939051693000 -0.0296118800403 -0.00342398732706 0.519638659997 29 | templeR0028.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.05932746295193329400 0.98312024330151082000 -0.17307466409173006000 0.94948800754006690000 -0.00205516590155378630 0.31379658989656145000 0.30814408265822768000 -0.18294907352565445000 -0.93358280876354183000 -0.0296133302663 -0.0104638360839 0.519735985312 30 | templeR0029.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.04085617948912668300 0.98315753616677781000 -0.17813486934349265000 0.98279680502378086000 -0.00740473917804992600 0.18454162097682264000 0.18011444315379183000 -0.18261004604395678000 -0.96654661473268999000 -0.0294802294097 -0.017428062139 0.520761069394 31 | templeR0030.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.02187598221295046500 0.98329680886213122000 -0.18068986436368856000 0.99856708067455469000 -0.01266114646423924800 0.05199500709980022000 0.04883878372068523700 -0.18156839221560722000 -0.98216479887691122000 -0.0292149526928 -0.0241923869131 0.52269561933 32 | templeR0031.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.00937296764199993530 0.98344162453868444000 -0.18098264724082042000 0.99925305205489368000 -0.01599729078633601100 -0.03517704715403165800 -0.03748980443482706500 -0.18051774929964823000 -0.98285698692700341000 -0.0289726466043 -0.0284423587627 0.524433248357 33 | templeR0032.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.01469342934183854600 -0.99573306146750762000 -0.09110309234444970200 0.99863024345655671000 -0.01003794245248637200 -0.05135052643564889200 0.05021692929753969500 -0.09173281861943144400 0.99451664138920282000 0.0253214159027 -0.0293792487736 0.618360066 34 | templeR0033.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.00344069629113946850 -0.99586227407284378000 -0.09081020145059000300 0.99933561911064872000 -0.00671916164933668900 0.03582140761425173200 -0.03628335687017435900 -0.09062661830386635500 0.99522376080409014000 0.0251047679644 -0.0251578300064 0.620169213551 35 | templeR0034.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.01363654728930748000 -0.99598585067933787000 -0.08846598117119695800 0.98568300171389711000 -0.00148022139463806730 0.16860257731394196000 -0.16805673063078255000 -0.08949857088903123700 0.98170613785313243000 0.0248682934353 -0.0184255570846 0.6222160467 36 | templeR0035.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.03024984704142087700 -0.99601761198976480000 -0.08386813077789044600 0.95444181867062872000 0.00386319621827520880 0.29837206720415643000 -0.29685983481547856000 -0.08907296066251421700 0.95075772211018139000 0.02475084721 -0.0114787519258 0.6233549331 37 | templeR0036.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.04610273394227399500 -0.99595699121457582000 -0.07709870020861223100 0.90616957770959716000 0.00921573639400264520 0.42281410411234677000 -0.42039414167737649000 -0.08935738275892947400 0.90293079678888799000 0.0247545251495 -0.00444138222871 0.623565549002 38 | templeR0037.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.06091231694352535600 -0.99580507011728536000 -0.06827848836405432700 0.84172768564816447000 0.01448188430858370400 0.53970804907862679000 -0.53645521048635192000 -0.09034676173267966500 0.83907882215347451000 0.0248792616217 0.00256097179509 0.622844136013 39 | templeR0038.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.07441431485673913300 -0.99556455977275171000 -0.05756489441395285000 0.76226612623790635000 0.01956766406619288600 0.64696789666354271000 -0.64297189871304494000 -0.09202344183674107700 0.76034125471255454000 0.0251228306692 0.00940335116174 0.621203567953 40 | templeR0039.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.08636778769614070200 -0.99523975203165982000 -0.04514909992939995800 0.66920287236824150000 0.02438232111996040500 0.74267962004547960000 -0.73804344104027464000 -0.09435750310793368500 0.66812314788867089000 0.0254808858594 0.0159636552164 0.618673120373 41 | templeR0040.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.10793659924390045000 -0.99055951509200579000 0.08450761861721302300 -0.32994878599451571000 0.04449292035991074500 0.94294972223262863000 -0.93780781035583538000 -0.12966197244580752000 -0.32203149494584499000 0.0313386715547 0.0461955496235 0.574657858455 42 | templeR0041.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 0.10064436337366003000 -0.98987287691280146000 0.10011193571939807000 -0.45281218231871551000 0.04402436503296685400 0.89051837871388495000 -0.88590735388350439000 -0.13495755938745446000 -0.44379569342131825000 0.0322465423181 0.0461686603603 0.567676168654 43 | templeR0042.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.09868778720769125200 -0.99342356952296929000 -0.05805456202825097500 0.72029150408413001000 -0.03105781339599184000 -0.69297587358527946000 0.68661551817612676000 -0.11020446335472237000 0.71861958396388448000 0.028650693588 -0.0548464785114 0.59189613682 44 | templeR0043.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.08513547925382919400 -0.99399869748797920000 -0.06869162659612815200 0.80631333030563868000 -0.02823128526067348500 -0.59081452919165756000 0.58532961956802643000 -0.10568625229769273000 0.80387788409161853000 0.0278557511485 -0.0516471860246 0.598117193954 45 | templeR0044.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.07028452998918902100 -0.99451747087193221000 -0.07742793407223566600 0.87794743962593247000 -0.02482290748598041700 -0.47811307921684382000 0.47356982388922148000 -0.10158160952868461000 0.87487873360088786000 0.0271265258805 -0.0476405218956 0.603860347957 46 | templeR0045.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.05439995112000559800 -0.99497063228547356000 -0.08410758709882369700 0.93391553816646533000 -0.02089350177384347000 -0.35688265460073498000 0.35333045847956862000 -0.09796378143513864700 0.93035513898593913000 0.0264760306379 -0.042897984106 0.609023113594 47 | templeR0046.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.03776520743937929200 -0.99535009493528070000 -0.08861138538240269400 0.97321885941264064000 -0.01651318947821050300 -0.22928664648604202000 0.22675722875052765000 -0.09489732918046089900 0.96931710813530791000 0.0259158736918 -0.0375042045812 0.613513359853 48 | templeR0047.png 1520.400000 0.000000 302.320000 0.000000 1525.900000 246.870000 0.000000 0.000000 1.000000 -0.02067714204649669800 -0.99564908739937330000 -0.09085895969899916700 0.99515604481568609000 -0.01176013624456452200 -0.09760197570904494100 0.09610880429798678000 -0.09243697288587854300 0.99106937384832272000 0.0254560509115 -0.0315554340517 0.617250959345 49 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: sfm5 2 | channels: 3 | - conda-forge 4 | - defaults 5 | dependencies: 6 | - _libgcc_mutex=0.1=main 7 | - attrs=19.3.0=py_0 8 | - backcall=0.1.0=py36_0 9 | - blas=1.0=mkl 10 | - bleach=3.1.0=py36_0 11 | - ca-certificates=2019.11.28=hecc5488_0 12 | - certifi=2019.11.28=py36_0 13 | - cycler=0.10.0=py36_0 14 | - dbus=1.13.12=h746ee38_0 15 | - decorator=4.4.1=py_0 16 | - defusedxml=0.6.0=py_0 17 | - entrypoints=0.3=py36_0 18 | - expat=2.2.6=he6710b0_0 19 | - fontconfig=2.13.0=h9420a91_0 20 | - freetype=2.9.1=h8a8886c_1 21 | - glib=2.63.1=h5a9c865_0 22 | - gmp=6.1.2=h6c8ec71_1 23 | - gst-plugins-base=1.14.0=hbbd80ab_1 24 | - gstreamer=1.14.0=hb453b48_1 25 | - icu=58.2=h9c2bf20_1 26 | - importlib_metadata=1.3.0=py36_0 27 | - intel-openmp=2019.4=243 28 | - ipykernel=5.1.3=py36h39e3cac_1 29 | - ipython=7.11.1=py36h39e3cac_0 30 | - ipython_genutils=0.2.0=py36_0 31 | - ipywidgets=7.5.1=py_0 32 | - jedi=0.15.2=py36_0 33 | - jinja2=2.10.3=py_0 34 | - jpeg=9b=h024ee3a_2 35 | - jsonschema=3.2.0=py36_0 36 | - jupyter=1.0.0=py36_7 37 | - jupyter_client=5.3.4=py36_0 38 | - jupyter_console=6.1.0=py_0 39 | - jupyter_core=4.6.1=py36_0 40 | - kiwisolver=1.1.0=py36he6710b0_0 41 | - ld_impl_linux-64=2.33.1=h53a641e_7 42 | - libedit=3.1.20181209=hc058e9b_0 43 | - libffi=3.2.1=hd88cf55_4 44 | - libgcc-ng=9.1.0=hdf63c60_0 45 | - libgfortran-ng=7.3.0=hdf63c60_0 46 | - libpng=1.6.37=hbc83047_0 47 | - libsodium=1.0.16=h1bed415_0 48 | - libstdcxx-ng=9.1.0=hdf63c60_0 49 | - libuuid=1.0.3=h1bed415_2 50 | - libxcb=1.13=h1bed415_1 51 | - libxml2=2.9.9=hea5a465_1 52 | - markupsafe=1.1.1=py36h7b6447c_0 53 | - matplotlib=3.1.1=py36h5429711_0 54 | - mistune=0.8.4=py36h7b6447c_0 55 | - mkl=2019.4=243 56 | - mkl-service=2.3.0=py36he904b0f_0 57 | - mkl_fft=1.0.15=py36ha843d7b_0 58 | - mkl_random=1.1.0=py36hd6b4f25_0 59 | - more-itertools=8.0.2=py_0 60 | - nbconvert=5.6.1=py36_0 61 | - nbformat=4.4.0=py36_0 62 | - ncurses=6.1=he6710b0_1 63 | - notebook=6.0.2=py36_0 64 | - numpy=1.18.1=py36h4f9e942_0 65 | - numpy-base=1.18.1=py36hde5b4d6_1 66 | - openssl=1.1.1d=h516909a_0 67 | - pandas=1.0.1=py36hb3f55d8_0 68 | - pandoc=2.2.3.2=0 69 | - pandocfilters=1.4.2=py36_1 70 | - parso=0.5.2=py_0 71 | - pcre=8.43=he6710b0_0 72 | - pexpect=4.7.0=py36_0 73 | - pickleshare=0.7.5=py36_0 74 | - pip=19.3.1=py36_0 75 | - prometheus_client=0.7.1=py_0 76 | - prompt_toolkit=3.0.2=py_0 77 | - ptyprocess=0.6.0=py36_0 78 | - pygments=2.5.2=py_0 79 | - pyntcloud=0.1.2=py_0 80 | - pyparsing=2.4.6=py_0 81 | - pyqt=5.9.2=py36h05f1152_2 82 | - pyrsistent=0.15.6=py36h7b6447c_0 83 | - python=3.6.10=h0371630_0 84 | - python-dateutil=2.8.1=py_0 85 | - pytz=2019.3=py_0 86 | - pyzmq=18.1.0=py36he6710b0_0 87 | - qt=5.9.7=h5867ecd_1 88 | - qtconsole=4.6.0=py_1 89 | - readline=7.0=h7b6447c_5 90 | - scipy=1.4.1=py36h0b6359f_0 91 | - send2trash=1.5.0=py36_0 92 | - setuptools=44.0.0=py36_0 93 | - sip=4.19.8=py36hf484d3e_0 94 | - six=1.13.0=py36_0 95 | - sqlite=3.30.1=h7b6447c_0 96 | - terminado=0.8.3=py36_0 97 | - testpath=0.4.4=py_0 98 | - tk=8.6.8=hbc83047_0 99 | - tornado=6.0.3=py36h7b6447c_0 100 | - traitlets=4.3.3=py36_0 101 | - wcwidth=0.1.7=py36_0 102 | - webencodings=0.5.1=py36_1 103 | - wheel=0.33.6=py36_0 104 | - widgetsnbextension=3.5.1=py36_0 105 | - xz=5.2.4=h14c3975_4 106 | - zeromq=4.3.1=he6710b0_3 107 | - zipp=0.6.0=py_0 108 | - zlib=1.2.11=h7b6447c_3 109 | - pip: 110 | - fastscript==0.1.4 111 | - nbdev==0.2.9 112 | - opencv-contrib-python==3.4.2.16 113 | - packaging==20.1 114 | - pyyaml==5.3 115 | prefix: /home/ryan/anaconda3/envs/sfm5 116 | -------------------------------------------------------------------------------- /main.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import cv2\n", 10 | "import pyntcloud\n", 11 | "import random\n", 12 | "import numpy as np\n", 13 | "import pandas as pd\n", 14 | "import matplotlib as mpl\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "import bundle_adjustment as b\n", 17 | "import matching as m\n", 18 | "import reconstruction as r\n", 19 | "\n", 20 | "%matplotlib inline\n", 21 | "mpl.rcParams['figure.dpi']= 200" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "num_matches before outlier removal: 59608\n", 34 | "Number of img pairs is 1034 out of possible 1035\n", 35 | "After outlier removal:\n", 36 | "Number of img pairs is 243 out of possible 1035\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "### This cell does matching between images and outlier removal\n", 42 | "n_imgs = 46 #46 if imgset = 'templering', 49 if imgset = 'Viking'\n", 43 | "\n", 44 | "images, keypoints, descriptors, K = m.find_features(n_imgs, imgset='templering')\n", 45 | "\n", 46 | "matcher = cv2.BFMatcher(cv2.NORM_L1)\n", 47 | "matches = m.find_matches(matcher, keypoints, descriptors)\n", 48 | "print('num_matches before outlier removal:', m.num_matches(matches))\n", 49 | "m.print_num_img_pairs(matches)\n", 50 | "\n", 51 | "matches = m.remove_outliers(matches, keypoints)\n", 52 | "print(\"After outlier removal:\")\n", 53 | "m.print_num_img_pairs(matches)\n", 54 | "\n", 55 | "img_adjacency, list_of_img_pairs = m.create_img_adjacency_matrix(n_imgs, matches)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 6, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "Triangulating: 436 points.\n", 68 | "initial image pair: [20, 23]\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "### This cell initializes the reconstruction\n", 74 | "best_pair = r.best_img_pair(img_adjacency, matches, keypoints, K, top_x_perc=0.2)\n", 75 | "R0, t0, R1, t1, points3d_with_views = r.initialize_reconstruction(keypoints, matches, K, best_pair[0], best_pair[1])\n", 76 | "\n", 77 | "R_mats = {best_pair[0]: R0, best_pair[1]: R1}\n", 78 | "t_vecs = {best_pair[0]: t0, best_pair[1]: t1}\n", 79 | "\n", 80 | "resected_imgs = [best_pair[0], best_pair[1]] \n", 81 | "unresected_imgs = [i for i in range(len(images)) if i not in resected_imgs] \n", 82 | "print('initial image pair:', resected_imgs)\n", 83 | "avg_err = 0" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 15, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | "Unresected image: 25, resected: 24\n", 96 | "rvec: [[ 0.50766114]\n", 97 | " [-2.10156888]\n", 98 | " [ 2.29867579]] \n", 99 | "\n", 100 | "tvec: [[ 0.0434132 ]\n", 101 | " [-1.80155935]\n", 102 | " [ 0.5155942 ]]\n", 103 | "Average error of reprojecting points used to resect image 25 back onto it is: 0.7049232652085571\n", 104 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 388\n", 105 | "Triangulating: 184 points.\n", 106 | "Average reprojection error for just-triangulated points on image 24 is: 6.068759133733349 pixels.\n", 107 | "Average reprojection error for just-triangulated points on image 25 is: 2.3039583504029206 pixels.\n", 108 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 109 | " 0 1 1.6929e+04 9.41e+05 \n", 110 | " 1 3 8.6274e+03 8.30e+03 4.84e-01 2.64e+05 \n", 111 | "`ftol` termination condition is satisfied.\n", 112 | "Function evaluations 3, initial cost 1.6929e+04, final cost 8.6274e+03, first-order optimality 2.64e+05.\n", 113 | "Average reprojection error on image 22 is 0.5204822007721859 pixels\n", 114 | "Average reprojection error on image 21 is 0.24117516066841338 pixels\n", 115 | "Average reprojection error on image 20 is 0.17898800455508623 pixels\n", 116 | "Average reprojection error on image 23 is 0.476234309610596 pixels\n", 117 | "Average reprojection error on image 24 is 1.5025285172347158 pixels\n", 118 | "Average reprojection error on image 19 is 0.5065232718591007 pixels\n", 119 | "Average reprojection error on image 25 is 1.0033061182254415 pixels\n", 120 | "Average reprojection error across all 7 resected images is 0.6327482261322199 pixels\n", 121 | "Unresected image: 18, resected: 19\n", 122 | "rvec: [[ 0.23439619]\n", 123 | " [-0.00803697]\n", 124 | " [-0.04270545]] \n", 125 | "\n", 126 | "tvec: [[0.02732089]\n", 127 | " [0.72987112]\n", 128 | " [0.06652131]]\n", 129 | "Average error of reprojecting points used to resect image 18 back onto it is: 0.609686985644368\n", 130 | "Fraction of Pnp inliers: 0.9895833333333334 num pts used in Pnp: 384\n", 131 | "Triangulating: 222 points.\n", 132 | "Average reprojection error for just-triangulated points on image 18 is: 0.23518107372318686 pixels.\n", 133 | "Average reprojection error for just-triangulated points on image 19 is: 8.150196250178945 pixels.\n", 134 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 135 | " 0 1 3.8819e+04 2.10e+06 \n", 136 | " 1 2 2.4010e+04 1.48e+04 4.50e+00 1.88e+06 \n", 137 | "`ftol` termination condition is satisfied.\n", 138 | "Function evaluations 2, initial cost 3.8819e+04, final cost 2.4010e+04, first-order optimality 1.88e+06.\n", 139 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 140 | " 0 1 2.4010e+04 1.88e+06 \n", 141 | " 1 2 8.3735e+03 1.56e+04 1.30e+00 1.09e+06 \n", 142 | " 2 3 6.1040e+03 2.27e+03 4.39e-01 5.23e+04 \n", 143 | " 3 4 6.0897e+03 1.43e+01 1.52e-01 3.17e+04 \n", 144 | "`ftol` termination condition is satisfied.\n", 145 | "Function evaluations 4, initial cost 2.4010e+04, final cost 6.0897e+03, first-order optimality 3.17e+04.\n", 146 | "Average reprojection error on image 22 is 0.4795398240081006 pixels\n", 147 | "Average reprojection error on image 21 is 0.22383700476160406 pixels\n", 148 | "Average reprojection error on image 20 is 0.2400935318310137 pixels\n", 149 | "Average reprojection error on image 23 is 0.3545048490392695 pixels\n", 150 | "Average reprojection error on image 24 is 0.1488031359171657 pixels\n", 151 | "Average reprojection error on image 19 is 0.17915710764240522 pixels\n", 152 | "Average reprojection error on image 25 is 0.1319684158459681 pixels\n", 153 | "Average reprojection error on image 18 is 0.1868619744120473 pixels\n", 154 | "Average reprojection error across all 8 resected images is 0.24309573043219676 pixels\n", 155 | "Unresected image: 26, resected: 25\n", 156 | "rvec: [[-0.45190309]\n", 157 | " [ 0.91902325]\n", 158 | " [-2.98199671]] \n", 159 | "\n", 160 | "tvec: [[ 0.11483467]\n", 161 | " [-2.1050705 ]\n", 162 | " [ 0.77554911]]\n", 163 | "Average error of reprojecting points used to resect image 26 back onto it is: 0.4482231764909142\n", 164 | "Fraction of Pnp inliers: 0.9891304347826086 num pts used in Pnp: 368\n", 165 | "Triangulating: 170 points.\n", 166 | "Average reprojection error for just-triangulated points on image 25 is: 8.157911090278684 pixels.\n", 167 | "Average reprojection error for just-triangulated points on image 26 is: 7.716439894282427 pixels.\n", 168 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 169 | " 0 1 5.0676e+04 8.32e+05 \n", 170 | " 1 2 6.4571e+03 4.42e+04 6.61e-01 3.60e+04 \n", 171 | "`ftol` termination condition is satisfied.\n", 172 | "Function evaluations 2, initial cost 5.0676e+04, final cost 6.4571e+03, first-order optimality 3.60e+04.\n", 173 | "Average reprojection error on image 22 is 0.4859708503672902 pixels\n", 174 | "Average reprojection error on image 21 is 0.22416783994188 pixels\n", 175 | "Average reprojection error on image 20 is 0.24790571049878535 pixels\n", 176 | "Average reprojection error on image 23 is 0.34766280590391174 pixels\n", 177 | "Average reprojection error on image 24 is 0.1589725002504631 pixels\n", 178 | "Average reprojection error on image 19 is 0.18190700938749504 pixels\n", 179 | "Average reprojection error on image 25 is 0.14121911147887692 pixels\n", 180 | "Average reprojection error on image 18 is 0.1874422652319784 pixels\n", 181 | "Average reprojection error on image 26 is 0.2181489566673722 pixels\n", 182 | "Average reprojection error across all 9 resected images is 0.24371078330311702 pixels\n", 183 | "Unresected image: 17, resected: 18\n", 184 | "rvec: [[ 0.3639808 ]\n", 185 | " [-0.00385548]\n", 186 | " [-0.05875055]] \n", 187 | "\n", 188 | "tvec: [[0.01276028]\n", 189 | " [1.11167821]\n", 190 | " [0.1988086 ]]\n", 191 | "Average error of reprojecting points used to resect image 17 back onto it is: 0.7645965743982077\n", 192 | "Fraction of Pnp inliers: 0.989769820971867 num pts used in Pnp: 391\n", 193 | "Triangulating: 145 points.\n", 194 | "Average reprojection error for just-triangulated points on image 17 is: 10.740403299977922 pixels.\n", 195 | "Average reprojection error for just-triangulated points on image 18 is: 11.634733160065487 pixels.\n", 196 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 197 | " 0 1 8.7452e+04 9.76e+05 \n", 198 | " 1 2 1.1154e+04 7.63e+04 2.11e+00 1.57e+06 \n", 199 | " 2 3 7.6192e+03 3.53e+03 5.95e-01 3.67e+05 \n", 200 | " 3 4 7.3334e+03 2.86e+02 2.61e-01 1.90e+05 \n", 201 | "`ftol` termination condition is satisfied.\n", 202 | "Function evaluations 4, initial cost 8.7452e+04, final cost 7.3334e+03, first-order optimality 1.90e+05.\n", 203 | "Average reprojection error on image 22 is 0.4396853260872267 pixels\n", 204 | "Average reprojection error on image 21 is 0.19801759467058858 pixels\n", 205 | "Average reprojection error on image 20 is 0.2555159163884728 pixels\n", 206 | "Average reprojection error on image 23 is 0.2809454430089793 pixels\n", 207 | "Average reprojection error on image 24 is 0.15495089311143545 pixels\n", 208 | "Average reprojection error on image 19 is 0.2669501964745836 pixels\n", 209 | "Average reprojection error on image 25 is 0.1308028139552076 pixels\n", 210 | "Average reprojection error on image 18 is 0.4029865409635224 pixels\n", 211 | "Average reprojection error on image 26 is 0.1692836450403817 pixels\n", 212 | "Average reprojection error on image 17 is 0.2851434309187453 pixels\n", 213 | "Average reprojection error across all 10 resected images is 0.2584281800619143 pixels\n", 214 | "Unresected image: 27, resected: 26\n", 215 | "rvec: [[ 0.14237847]\n", 216 | " [-1.35406382]\n", 217 | " [ 2.91975306]] \n", 218 | "\n", 219 | "tvec: [[ 0.16040015]\n", 220 | " [-2.38507332]\n", 221 | " [ 1.06239096]]\n", 222 | "Average error of reprojecting points used to resect image 27 back onto it is: 0.38264224671936004\n", 223 | "Fraction of Pnp inliers: 0.9970059880239521 num pts used in Pnp: 334\n", 224 | "Triangulating: 177 points.\n", 225 | "Average reprojection error for just-triangulated points on image 26 is: 1.6762480710259748 pixels.\n", 226 | "Average reprojection error for just-triangulated points on image 27 is: 1.5670903233422804 pixels.\n", 227 | "Average reprojection error on image 22 is 0.4396853260872267 pixels\n", 228 | "Average reprojection error on image 21 is 0.19801759467058858 pixels\n", 229 | "Average reprojection error on image 20 is 0.2555159163884728 pixels\n", 230 | "Average reprojection error on image 23 is 0.2809454430089793 pixels\n", 231 | "Average reprojection error on image 24 is 0.15495089311143545 pixels\n", 232 | "Average reprojection error on image 19 is 0.2669501964745836 pixels\n", 233 | "Average reprojection error on image 25 is 0.1308028139552076 pixels\n", 234 | "Average reprojection error on image 18 is 0.4029865409635224 pixels\n", 235 | "Average reprojection error on image 26 is 0.5423363770675844 pixels\n", 236 | "Average reprojection error on image 17 is 0.2851434309187453 pixels\n", 237 | "Average reprojection error on image 27 is 0.7929109542776207 pixels\n", 238 | "Average reprojection error across all 11 resected images is 0.3409314079021788 pixels\n" 239 | ] 240 | }, 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "Unresected image: 16, resected: 17\n", 246 | "rvec: [[0.02223558]\n", 247 | " [0.89711449]\n", 248 | " [2.92244099]] \n", 249 | "\n", 250 | "tvec: [[0.04332104]\n", 251 | " [1.52612557]\n", 252 | " [0.37933195]]\n", 253 | "Average error of reprojecting points used to resect image 16 back onto it is: 0.7714300840380935\n", 254 | "Fraction of Pnp inliers: 0.9905362776025236 num pts used in Pnp: 317\n", 255 | "Triangulating: 174 points.\n", 256 | "Average reprojection error for just-triangulated points on image 16 is: 0.8507336397063667 pixels.\n", 257 | "Average reprojection error for just-triangulated points on image 17 is: 5.601516005877062 pixels.\n", 258 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 259 | " 0 1 2.0770e+04 1.15e+06 \n", 260 | " 1 2 9.9349e+03 1.08e+04 1.72e+00 7.00e+05 \n", 261 | "`ftol` termination condition is satisfied.\n", 262 | "Function evaluations 2, initial cost 2.0770e+04, final cost 9.9349e+03, first-order optimality 7.00e+05.\n", 263 | "Average reprojection error on image 22 is 0.4503236479381985 pixels\n", 264 | "Average reprojection error on image 21 is 0.21118728108364268 pixels\n", 265 | "Average reprojection error on image 20 is 0.2791018830678146 pixels\n", 266 | "Average reprojection error on image 23 is 0.26920524265775436 pixels\n", 267 | "Average reprojection error on image 24 is 0.1657221009574476 pixels\n", 268 | "Average reprojection error on image 19 is 0.638239129926634 pixels\n", 269 | "Average reprojection error on image 25 is 0.1477203293078473 pixels\n", 270 | "Average reprojection error on image 18 is 0.5691057665216155 pixels\n", 271 | "Average reprojection error on image 26 is 0.13620598025765232 pixels\n", 272 | "Average reprojection error on image 17 is 0.8829454758133338 pixels\n", 273 | "Average reprojection error on image 27 is 0.2601625953767908 pixels\n", 274 | "Average reprojection error on image 16 is 0.3652052583292542 pixels\n", 275 | "Average reprojection error across all 12 resected images is 0.3645937242698322 pixels\n", 276 | "Unresected image: 28, resected: 27\n", 277 | "rvec: [[-0.17868015]\n", 278 | " [-2.85964714]\n", 279 | " [-1.39912133]] \n", 280 | "\n", 281 | "tvec: [[ 0.18314722]\n", 282 | " [-2.63054089]\n", 283 | " [ 1.38500981]]\n", 284 | "Average error of reprojecting points used to resect image 28 back onto it is: 0.34834735082732543\n", 285 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 306\n", 286 | "Triangulating: 191 points.\n", 287 | "Average reprojection error for just-triangulated points on image 27 is: 1.8244732680234885 pixels.\n", 288 | "Average reprojection error for just-triangulated points on image 28 is: 1.2848304505923855 pixels.\n", 289 | "Average reprojection error on image 22 is 0.4503236479381985 pixels\n", 290 | "Average reprojection error on image 21 is 0.21118728108364268 pixels\n", 291 | "Average reprojection error on image 20 is 0.2791018830678146 pixels\n", 292 | "Average reprojection error on image 23 is 0.26920524265775436 pixels\n", 293 | "Average reprojection error on image 24 is 0.1657221009574476 pixels\n", 294 | "Average reprojection error on image 19 is 0.638239129926634 pixels\n", 295 | "Average reprojection error on image 25 is 0.1477203293078473 pixels\n", 296 | "Average reprojection error on image 18 is 0.5691057665216155 pixels\n", 297 | "Average reprojection error on image 26 is 0.13620598025765232 pixels\n", 298 | "Average reprojection error on image 17 is 0.8829454758133338 pixels\n", 299 | "Average reprojection error on image 27 is 0.6857798866524589 pixels\n", 300 | "Average reprojection error on image 16 is 0.3652052583292542 pixels\n", 301 | "Average reprojection error on image 28 is 0.7082432704553455 pixels\n", 302 | "Average reprojection error across all 13 resected images is 0.42376809638223073 pixels\n", 303 | "Unresected image: 15, resected: 16\n", 304 | "rvec: [[-0.00672599]\n", 305 | " [ 0.99488169]\n", 306 | " [ 2.87150186]] \n", 307 | "\n", 308 | "tvec: [[0.10663807]\n", 309 | " [1.88610717]\n", 310 | " [0.61034582]]\n", 311 | "Average error of reprojecting points used to resect image 15 back onto it is: 0.7527477398989713\n", 312 | "Fraction of Pnp inliers: 0.9935064935064936 num pts used in Pnp: 308\n", 313 | "Triangulating: 168 points.\n", 314 | "Average reprojection error for just-triangulated points on image 15 is: 1.2632210218649593 pixels.\n", 315 | "Average reprojection error for just-triangulated points on image 16 is: 2.633964038248285 pixels.\n", 316 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 317 | " 0 1 1.4943e+04 7.00e+05 \n", 318 | " 1 2 9.1803e+03 5.76e+03 9.84e-01 1.49e+05 \n", 319 | " 2 3 9.0491e+03 1.31e+02 3.53e-01 1.17e+05 \n", 320 | "`ftol` termination condition is satisfied.\n", 321 | "Function evaluations 3, initial cost 1.4943e+04, final cost 9.0491e+03, first-order optimality 1.17e+05.\n", 322 | "Average reprojection error on image 22 is 0.3987340420260805 pixels\n", 323 | "Average reprojection error on image 21 is 0.19303065778979042 pixels\n", 324 | "Average reprojection error on image 20 is 0.26622529941588813 pixels\n", 325 | "Average reprojection error on image 23 is 0.23692934045304614 pixels\n", 326 | "Average reprojection error on image 24 is 0.168324340251932 pixels\n", 327 | "Average reprojection error on image 19 is 0.36749834631738587 pixels\n", 328 | "Average reprojection error on image 25 is 0.15287291828608024 pixels\n", 329 | "Average reprojection error on image 18 is 0.2920439877086478 pixels\n", 330 | "Average reprojection error on image 26 is 0.1433146412596668 pixels\n", 331 | "Average reprojection error on image 17 is 0.17974078069128793 pixels\n", 332 | "Average reprojection error on image 27 is 0.11260352169587537 pixels\n", 333 | "Average reprojection error on image 16 is 0.14851534507740125 pixels\n", 334 | "Average reprojection error on image 28 is 0.14248177052880392 pixels\n", 335 | "Average reprojection error on image 15 is 0.19241305589788044 pixels\n", 336 | "Average reprojection error across all 14 resected images is 0.21390914624284046 pixels\n", 337 | "Unresected image: 29, resected: 28\n", 338 | "rvec: [[-0.98016842]\n", 339 | " [-0.61051607]\n", 340 | " [ 3.10161155]] \n", 341 | "\n", 342 | "tvec: [[ 0.21238493]\n", 343 | " [-2.78131765]\n", 344 | " [ 1.5522883 ]]\n", 345 | "Average error of reprojecting points used to resect image 29 back onto it is: 0.4193134455855049\n", 346 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 315\n", 347 | "Triangulating: 233 points.\n", 348 | "Average reprojection error for just-triangulated points on image 28 is: 1.2723421723959447 pixels.\n", 349 | "Average reprojection error for just-triangulated points on image 29 is: 0.16112032073516805 pixels.\n", 350 | "Average reprojection error on image 22 is 0.3987340420260805 pixels\n", 351 | "Average reprojection error on image 21 is 0.19303065778979042 pixels\n", 352 | "Average reprojection error on image 20 is 0.26622529941588813 pixels\n", 353 | "Average reprojection error on image 23 is 0.23692934045304614 pixels\n", 354 | "Average reprojection error on image 24 is 0.168324340251932 pixels\n", 355 | "Average reprojection error on image 19 is 0.36749834631738587 pixels\n", 356 | "Average reprojection error on image 25 is 0.15287291828608024 pixels\n", 357 | "Average reprojection error on image 18 is 0.2920439877086478 pixels\n", 358 | "Average reprojection error on image 26 is 0.1433146412596668 pixels\n", 359 | "Average reprojection error on image 17 is 0.17974078069128793 pixels\n", 360 | "Average reprojection error on image 27 is 0.11260352169587537 pixels\n", 361 | "Average reprojection error on image 16 is 0.14851534507740125 pixels\n", 362 | "Average reprojection error on image 28 is 0.5031084467411929 pixels\n", 363 | "Average reprojection error on image 15 is 0.19241305589788044 pixels\n", 364 | "Average reprojection error on image 29 is 0.3095342519903797 pixels\n", 365 | "Average reprojection error across all 15 resected images is 0.2443259317068357 pixels\n", 366 | "Unresected image: 14, resected: 15\n", 367 | "rvec: [[ 0.8645873 ]\n", 368 | " [-0.01862852]\n", 369 | " [-0.12603632]] \n", 370 | "\n", 371 | "tvec: [[0.14735078]\n", 372 | " [2.37798487]\n", 373 | " [1.09118484]]\n", 374 | "Average error of reprojecting points used to resect image 14 back onto it is: 0.49456932394801106\n", 375 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 198\n", 376 | "Triangulating: 92 points.\n", 377 | "Average reprojection error for just-triangulated points on image 14 is: 2.7665041357803553 pixels.\n", 378 | "Average reprojection error for just-triangulated points on image 15 is: 5.8185278286798905 pixels.\n", 379 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 380 | " 0 1 1.5149e+04 2.82e+05 \n", 381 | " 1 2 9.1407e+03 6.01e+03 9.23e-01 5.82e+04 \n", 382 | "`ftol` termination condition is satisfied.\n", 383 | "Function evaluations 2, initial cost 1.5149e+04, final cost 9.1407e+03, first-order optimality 5.82e+04.\n", 384 | "Average reprojection error on image 22 is 0.3838363647551715 pixels\n", 385 | "Average reprojection error on image 21 is 0.19357493331989883 pixels\n", 386 | "Average reprojection error on image 20 is 0.267425351326115 pixels\n", 387 | "Average reprojection error on image 23 is 0.2351497947019424 pixels\n", 388 | "Average reprojection error on image 24 is 0.16792269845799251 pixels\n", 389 | "Average reprojection error on image 19 is 0.3241850056923351 pixels\n", 390 | "Average reprojection error on image 25 is 0.1567349785024088 pixels\n", 391 | "Average reprojection error on image 18 is 0.29243160168358956 pixels\n", 392 | "Average reprojection error on image 26 is 0.14672556440139883 pixels\n", 393 | "Average reprojection error on image 17 is 0.18315272162417626 pixels\n", 394 | "Average reprojection error on image 27 is 0.12020670871482017 pixels\n", 395 | "Average reprojection error on image 16 is 0.1511304368324598 pixels\n", 396 | "Average reprojection error on image 28 is 0.11925037636373875 pixels\n", 397 | "Average reprojection error on image 15 is 0.18053947017337724 pixels\n", 398 | "Average reprojection error on image 29 is 0.2242622414789627 pixels\n", 399 | "Average reprojection error on image 14 is 0.18289274333957034 pixels\n", 400 | "Average reprojection error across all 16 resected images is 0.20808881196049733 pixels\n" 401 | ] 402 | }, 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "Unresected image: 30, resected: 29\n", 408 | "rvec: [[-224.63737942]\n", 409 | " [ 246.59591333]\n", 410 | " [ -62.59257277]] \n", 411 | "\n", 412 | "tvec: [[ 0.26766877]\n", 413 | " [-2.96294274]\n", 414 | " [ 1.91192027]]\n", 415 | "Average error of reprojecting points used to resect image 30 back onto it is: 0.5679263030803356\n", 416 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 307\n", 417 | "Triangulating: 143 points.\n", 418 | "Average reprojection error for just-triangulated points on image 29 is: 2.888277276969773 pixels.\n", 419 | "Average reprojection error for just-triangulated points on image 30 is: 0.32108702199883465 pixels.\n", 420 | "Average reprojection error on image 22 is 0.3838363647551715 pixels\n", 421 | "Average reprojection error on image 21 is 0.19357493331989883 pixels\n", 422 | "Average reprojection error on image 20 is 0.267425351326115 pixels\n", 423 | "Average reprojection error on image 23 is 0.2351497947019424 pixels\n", 424 | "Average reprojection error on image 24 is 0.16792269845799251 pixels\n", 425 | "Average reprojection error on image 19 is 0.3241850056923351 pixels\n", 426 | "Average reprojection error on image 25 is 0.1567349785024088 pixels\n", 427 | "Average reprojection error on image 18 is 0.29243160168358956 pixels\n", 428 | "Average reprojection error on image 26 is 0.14672556440139883 pixels\n", 429 | "Average reprojection error on image 17 is 0.18315272162417626 pixels\n", 430 | "Average reprojection error on image 27 is 0.12020670871482017 pixels\n", 431 | "Average reprojection error on image 16 is 0.1511304368324598 pixels\n", 432 | "Average reprojection error on image 28 is 0.11925037636373875 pixels\n", 433 | "Average reprojection error on image 15 is 0.18053947017337724 pixels\n", 434 | "Average reprojection error on image 29 is 0.7755707075790872 pixels\n", 435 | "Average reprojection error on image 14 is 0.18289274333957034 pixels\n", 436 | "Average reprojection error on image 30 is 0.48948626486998736 pixels\n", 437 | "Average reprojection error across all 17 resected images is 0.25707151307870996 pixels\n", 438 | "Unresected image: 13, resected: 14\n", 439 | "rvec: [[ 0.33852904]\n", 440 | " [-2.19786684]\n", 441 | " [ 2.19321724]] \n", 442 | "\n", 443 | "tvec: [[0.18215134]\n", 444 | " [2.64430268]\n", 445 | " [1.42729308]]\n", 446 | "Average error of reprojecting points used to resect image 13 back onto it is: 0.9229965156446996\n", 447 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 165\n", 448 | "Triangulating: 174 points.\n", 449 | "Average reprojection error for just-triangulated points on image 13 is: 0.26329506451234097 pixels.\n", 450 | "Average reprojection error for just-triangulated points on image 14 is: 0.34868534677386104 pixels.\n", 451 | "Average reprojection error on image 22 is 0.3838363647551715 pixels\n", 452 | "Average reprojection error on image 21 is 0.19357493331989883 pixels\n", 453 | "Average reprojection error on image 20 is 0.267425351326115 pixels\n", 454 | "Average reprojection error on image 23 is 0.2351497947019424 pixels\n", 455 | "Average reprojection error on image 24 is 0.16792269845799251 pixels\n", 456 | "Average reprojection error on image 19 is 0.3241850056923351 pixels\n", 457 | "Average reprojection error on image 25 is 0.1567349785024088 pixels\n", 458 | "Average reprojection error on image 18 is 0.29243160168358956 pixels\n", 459 | "Average reprojection error on image 26 is 0.14672556440139883 pixels\n", 460 | "Average reprojection error on image 17 is 0.18315272162417626 pixels\n", 461 | "Average reprojection error on image 27 is 0.12020670871482017 pixels\n", 462 | "Average reprojection error on image 16 is 0.1511304368324598 pixels\n", 463 | "Average reprojection error on image 28 is 0.11925037636373875 pixels\n", 464 | "Average reprojection error on image 15 is 0.18053947017337724 pixels\n", 465 | "Average reprojection error on image 29 is 0.7755707075790872 pixels\n", 466 | "Average reprojection error on image 14 is 0.24506496962742935 pixels\n", 467 | "Average reprojection error on image 30 is 0.48948626486998736 pixels\n", 468 | "Average reprojection error on image 13 is 0.5850364305870773 pixels\n", 469 | "Average reprojection error across all 18 resected images is 0.278745798845167 pixels\n", 470 | "Unresected image: 31, resected: 30\n", 471 | "rvec: [[-1.28038236]\n", 472 | " [-0.02067599]\n", 473 | " [ 0.15838795]] \n", 474 | "\n", 475 | "tvec: [[ 0.30626841]\n", 476 | " [-3.08619057]\n", 477 | " [ 2.27442237]]\n", 478 | "Average error of reprojecting points used to resect image 31 back onto it is: 1.3621844701946857\n", 479 | "Fraction of Pnp inliers: 0.9924242424242424 num pts used in Pnp: 264\n", 480 | "Triangulating: 153 points.\n", 481 | "Average reprojection error for just-triangulated points on image 30 is: 0.21263002939678208 pixels.\n", 482 | "Average reprojection error for just-triangulated points on image 31 is: 0.21278563529099861 pixels.\n", 483 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 484 | " 0 1 1.2361e+04 2.89e+05 \n", 485 | " 1 2 9.3333e+03 3.03e+03 1.00e+00 3.30e+04 \n", 486 | " 2 3 9.3211e+03 1.22e+01 8.03e-02 1.04e+03 \n", 487 | "`ftol` termination condition is satisfied.\n", 488 | "Function evaluations 3, initial cost 1.2361e+04, final cost 9.3211e+03, first-order optimality 1.04e+03.\n", 489 | "Average reprojection error on image 22 is 0.38266310383661256 pixels\n", 490 | "Average reprojection error on image 21 is 0.19462108267437528 pixels\n", 491 | "Average reprojection error on image 20 is 0.26657868356259323 pixels\n", 492 | "Average reprojection error on image 23 is 0.23609711751857793 pixels\n", 493 | "Average reprojection error on image 24 is 0.17206988407300422 pixels\n", 494 | "Average reprojection error on image 19 is 0.3240013172458706 pixels\n", 495 | "Average reprojection error on image 25 is 0.16164875331532186 pixels\n", 496 | "Average reprojection error on image 18 is 0.29237111115501974 pixels\n", 497 | "Average reprojection error on image 26 is 0.15246777189920652 pixels\n", 498 | "Average reprojection error on image 17 is 0.18571121515227984 pixels\n", 499 | "Average reprojection error on image 27 is 0.13328257292977186 pixels\n", 500 | "Average reprojection error on image 16 is 0.1557359237620612 pixels\n", 501 | "Average reprojection error on image 28 is 0.14461053208169164 pixels\n", 502 | "Average reprojection error on image 15 is 0.17016649742693576 pixels\n", 503 | "Average reprojection error on image 29 is 0.1313498594718248 pixels\n", 504 | "Average reprojection error on image 14 is 0.12622455873965058 pixels\n", 505 | "Average reprojection error on image 30 is 0.13276995816174278 pixels\n", 506 | "Average reprojection error on image 13 is 0.14166705564610982 pixels\n", 507 | "Average reprojection error on image 31 is 0.1601232346557731 pixels\n", 508 | "Average reprojection error across all 19 resected images is 0.1928505385951802 pixels\n", 509 | "Unresected image: 12, resected: 13\n", 510 | "rvec: [[ 1.11614469]\n", 511 | " [-0.01166087]\n", 512 | " [-0.15322235]] \n", 513 | "\n", 514 | "tvec: [[0.24792825]\n", 515 | " [2.84215025]\n", 516 | " [1.80805229]]\n", 517 | "Average error of reprojecting points used to resect image 12 back onto it is: 0.41709280425151435\n", 518 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 126\n", 519 | "Triangulating: 103 points.\n", 520 | "Average reprojection error for just-triangulated points on image 12 is: 0.8919742357915355 pixels.\n", 521 | "Average reprojection error for just-triangulated points on image 13 is: 2.8253730029208444 pixels.\n", 522 | "Average reprojection error on image 22 is 0.38266310383661256 pixels\n", 523 | "Average reprojection error on image 21 is 0.19462108267437528 pixels\n", 524 | "Average reprojection error on image 20 is 0.26657868356259323 pixels\n", 525 | "Average reprojection error on image 23 is 0.23609711751857793 pixels\n", 526 | "Average reprojection error on image 24 is 0.17206988407300422 pixels\n", 527 | "Average reprojection error on image 19 is 0.3240013172458706 pixels\n", 528 | "Average reprojection error on image 25 is 0.16164875331532186 pixels\n", 529 | "Average reprojection error on image 18 is 0.29237111115501974 pixels\n", 530 | "Average reprojection error on image 26 is 0.15246777189920652 pixels\n", 531 | "Average reprojection error on image 17 is 0.18571121515227984 pixels\n", 532 | "Average reprojection error on image 27 is 0.13328257292977186 pixels\n", 533 | "Average reprojection error on image 16 is 0.1557359237620612 pixels\n", 534 | "Average reprojection error on image 28 is 0.14461053208169164 pixels\n", 535 | "Average reprojection error on image 15 is 0.17016649742693576 pixels\n", 536 | "Average reprojection error on image 29 is 0.1313498594718248 pixels\n", 537 | "Average reprojection error on image 14 is 0.12622455873965058 pixels\n", 538 | "Average reprojection error on image 30 is 0.13276995816174278 pixels\n", 539 | "Average reprojection error on image 13 is 0.7684736601116378 pixels\n", 540 | "Average reprojection error on image 31 is 0.1601232346557731 pixels\n", 541 | "Average reprojection error on image 12 is 0.6311110181212577 pixels\n", 542 | "Average reprojection error across all 20 resected images is 0.24610389279476053 pixels\n", 543 | "Unresected image: 32, resected: 31\n", 544 | "rvec: [[-1.40473018]\n", 545 | " [-0.00450688]\n", 546 | " [ 0.20546192]] \n", 547 | "\n", 548 | "tvec: [[ 0.37044605]\n", 549 | " [-3.18504252]\n", 550 | " [ 2.69507528]]\n", 551 | "Average error of reprojecting points used to resect image 32 back onto it is: 0.5634552067912862\n", 552 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 252\n", 553 | "Triangulating: 209 points.\n", 554 | "Average reprojection error for just-triangulated points on image 31 is: 2.1534628874693675 pixels.\n", 555 | "Average reprojection error for just-triangulated points on image 32 is: 0.18219373040366557 pixels.\n", 556 | "Average reprojection error on image 22 is 0.38266310383661256 pixels\n", 557 | "Average reprojection error on image 21 is 0.19462108267437528 pixels\n", 558 | "Average reprojection error on image 20 is 0.26657868356259323 pixels\n", 559 | "Average reprojection error on image 23 is 0.23609711751857793 pixels\n", 560 | "Average reprojection error on image 24 is 0.17206988407300422 pixels\n", 561 | "Average reprojection error on image 19 is 0.3240013172458706 pixels\n", 562 | "Average reprojection error on image 25 is 0.16164875331532186 pixels\n", 563 | "Average reprojection error on image 18 is 0.29237111115501974 pixels\n", 564 | "Average reprojection error on image 26 is 0.15246777189920652 pixels\n", 565 | "Average reprojection error on image 17 is 0.18571121515227984 pixels\n", 566 | "Average reprojection error on image 27 is 0.13328257292977186 pixels\n", 567 | "Average reprojection error on image 16 is 0.1557359237620612 pixels\n", 568 | "Average reprojection error on image 28 is 0.14461053208169164 pixels\n", 569 | "Average reprojection error on image 15 is 0.17016649742693576 pixels\n", 570 | "Average reprojection error on image 29 is 0.1313498594718248 pixels\n", 571 | "Average reprojection error on image 14 is 0.12622455873965058 pixels\n", 572 | "Average reprojection error on image 30 is 0.13276995816174278 pixels\n" 573 | ] 574 | }, 575 | { 576 | "name": "stdout", 577 | "output_type": "stream", 578 | "text": [ 579 | "Average reprojection error on image 13 is 0.7684736601116378 pixels\n", 580 | "Average reprojection error on image 31 is 0.825631201809194 pixels\n", 581 | "Average reprojection error on image 12 is 0.6311110181212577 pixels\n", 582 | "Average reprojection error on image 32 is 0.39060564374354056 pixels\n", 583 | "Average reprojection error across all 21 resected images is 0.2846757841329606 pixels\n", 584 | "Unresected image: 11, resected: 12\n", 585 | "rvec: [[ 1.25347452]\n", 586 | " [-0.01066654]\n", 587 | " [-0.18293598]] \n", 588 | "\n", 589 | "tvec: [[0.32637766]\n", 590 | " [2.98615666]\n", 591 | " [2.14799688]]\n", 592 | "Average error of reprojecting points used to resect image 11 back onto it is: 1.481981181654146\n", 593 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 71\n", 594 | "Triangulating: 128 points.\n", 595 | "Average reprojection error for just-triangulated points on image 11 is: 0.38045077461109367 pixels.\n", 596 | "Average reprojection error for just-triangulated points on image 12 is: 0.36729486661168453 pixels.\n", 597 | "Average reprojection error on image 22 is 0.38266310383661256 pixels\n", 598 | "Average reprojection error on image 21 is 0.19462108267437528 pixels\n", 599 | "Average reprojection error on image 20 is 0.26657868356259323 pixels\n", 600 | "Average reprojection error on image 23 is 0.23609711751857793 pixels\n", 601 | "Average reprojection error on image 24 is 0.17206988407300422 pixels\n", 602 | "Average reprojection error on image 19 is 0.3240013172458706 pixels\n", 603 | "Average reprojection error on image 25 is 0.16164875331532186 pixels\n", 604 | "Average reprojection error on image 18 is 0.29237111115501974 pixels\n", 605 | "Average reprojection error on image 26 is 0.15246777189920652 pixels\n", 606 | "Average reprojection error on image 17 is 0.18571121515227984 pixels\n", 607 | "Average reprojection error on image 27 is 0.13328257292977186 pixels\n", 608 | "Average reprojection error on image 16 is 0.1557359237620612 pixels\n", 609 | "Average reprojection error on image 28 is 0.14461053208169164 pixels\n", 610 | "Average reprojection error on image 15 is 0.17016649742693576 pixels\n", 611 | "Average reprojection error on image 29 is 0.1313498594718248 pixels\n", 612 | "Average reprojection error on image 14 is 0.12622455873965058 pixels\n", 613 | "Average reprojection error on image 30 is 0.13276995816174278 pixels\n", 614 | "Average reprojection error on image 13 is 0.7684736601116378 pixels\n", 615 | "Average reprojection error on image 31 is 0.825631201809194 pixels\n", 616 | "Average reprojection error on image 12 is 0.5359885747600595 pixels\n", 617 | "Average reprojection error on image 32 is 0.39060564374354056 pixels\n", 618 | "Average reprojection error on image 11 is 0.7734591107922919 pixels\n", 619 | "Average reprojection error across all 22 resected images is 0.3025694606465121 pixels\n", 620 | "Unresected image: 33, resected: 32\n", 621 | "rvec: [[-1.48695502]\n", 622 | " [ 0.02237666]\n", 623 | " [ 0.26146418]] \n", 624 | "\n", 625 | "tvec: [[ 0.41585629]\n", 626 | " [-3.22698933]\n", 627 | " [ 3.05649414]]\n", 628 | "Average error of reprojecting points used to resect image 33 back onto it is: 1.3821083931370597\n", 629 | "Fraction of Pnp inliers: 0.9960159362549801 num pts used in Pnp: 251\n", 630 | "Triangulating: 122 points.\n", 631 | "Average reprojection error for just-triangulated points on image 32 is: 0.2890787717775695 pixels.\n", 632 | "Average reprojection error for just-triangulated points on image 33 is: 0.29099057356349184 pixels.\n", 633 | "Average reprojection error on image 22 is 0.38266310383661256 pixels\n", 634 | "Average reprojection error on image 21 is 0.19462108267437528 pixels\n", 635 | "Average reprojection error on image 20 is 0.26657868356259323 pixels\n", 636 | "Average reprojection error on image 23 is 0.23609711751857793 pixels\n", 637 | "Average reprojection error on image 24 is 0.17206988407300422 pixels\n", 638 | "Average reprojection error on image 19 is 0.3240013172458706 pixels\n", 639 | "Average reprojection error on image 25 is 0.16164875331532186 pixels\n", 640 | "Average reprojection error on image 18 is 0.29237111115501974 pixels\n", 641 | "Average reprojection error on image 26 is 0.15246777189920652 pixels\n", 642 | "Average reprojection error on image 17 is 0.18571121515227984 pixels\n", 643 | "Average reprojection error on image 27 is 0.13328257292977186 pixels\n", 644 | "Average reprojection error on image 16 is 0.1557359237620612 pixels\n", 645 | "Average reprojection error on image 28 is 0.14461053208169164 pixels\n", 646 | "Average reprojection error on image 15 is 0.17016649742693576 pixels\n", 647 | "Average reprojection error on image 29 is 0.1313498594718248 pixels\n", 648 | "Average reprojection error on image 14 is 0.12622455873965058 pixels\n", 649 | "Average reprojection error on image 30 is 0.13276995816174278 pixels\n", 650 | "Average reprojection error on image 13 is 0.7684736601116378 pixels\n", 651 | "Average reprojection error on image 31 is 0.825631201809194 pixels\n", 652 | "Average reprojection error on image 12 is 0.5359885747600595 pixels\n", 653 | "Average reprojection error on image 32 is 0.36935988322922075 pixels\n", 654 | "Average reprojection error on image 11 is 0.7734591107922919 pixels\n", 655 | "Average reprojection error on image 33 is 1.02522803391996 pixels\n", 656 | "Average reprojection error across all 23 resected images is 0.33306566989690894 pixels\n", 657 | "Unresected image: 10, resected: 11\n", 658 | "rvec: [[ 1882.2191142 ]\n", 659 | " [-3782.7312407 ]\n", 660 | " [-5481.41061078]] \n", 661 | "\n", 662 | "tvec: [[0.39829493]\n", 663 | " [3.09102697]\n", 664 | " [2.55867544]]\n", 665 | "Average error of reprojecting points used to resect image 10 back onto it is: 1.285511550646719\n", 666 | "Fraction of Pnp inliers: 0.95 num pts used in Pnp: 100\n", 667 | "Triangulating: 94 points.\n", 668 | "Average reprojection error for just-triangulated points on image 10 is: 0.14919176040639176 pixels.\n", 669 | "Average reprojection error for just-triangulated points on image 11 is: 0.1521113276719971 pixels.\n", 670 | "Average reprojection error on image 22 is 0.38266310383661256 pixels\n", 671 | "Average reprojection error on image 21 is 0.19462108267437528 pixels\n", 672 | "Average reprojection error on image 20 is 0.26657868356259323 pixels\n", 673 | "Average reprojection error on image 23 is 0.23609711751857793 pixels\n", 674 | "Average reprojection error on image 24 is 0.17206988407300422 pixels\n", 675 | "Average reprojection error on image 19 is 0.3240013172458706 pixels\n", 676 | "Average reprojection error on image 25 is 0.16164875331532186 pixels\n", 677 | "Average reprojection error on image 18 is 0.29237111115501974 pixels\n", 678 | "Average reprojection error on image 26 is 0.15246777189920652 pixels\n", 679 | "Average reprojection error on image 17 is 0.18571121515227984 pixels\n", 680 | "Average reprojection error on image 27 is 0.13328257292977186 pixels\n", 681 | "Average reprojection error on image 16 is 0.1557359237620612 pixels\n", 682 | "Average reprojection error on image 28 is 0.14461053208169164 pixels\n", 683 | "Average reprojection error on image 15 is 0.17016649742693576 pixels\n", 684 | "Average reprojection error on image 29 is 0.1313498594718248 pixels\n", 685 | "Average reprojection error on image 14 is 0.12622455873965058 pixels\n", 686 | "Average reprojection error on image 30 is 0.13276995816174278 pixels\n", 687 | "Average reprojection error on image 13 is 0.7684736601116378 pixels\n", 688 | "Average reprojection error on image 31 is 0.825631201809194 pixels\n", 689 | "Average reprojection error on image 12 is 0.5359885747600595 pixels\n", 690 | "Average reprojection error on image 32 is 0.36935988322922075 pixels\n", 691 | "Average reprojection error on image 11 is 0.5741188663782724 pixels\n", 692 | "Average reprojection error on image 33 is 1.02522803391996 pixels\n", 693 | "Average reprojection error on image 10 is 0.7345720763139041 pixels\n", 694 | "Average reprojection error across all 24 resected images is 0.3414892599803663 pixels\n", 695 | "Unresected image: 34, resected: 33\n", 696 | "rvec: [[-1.59173869]\n", 697 | " [-0.0048068 ]\n", 698 | " [ 0.2388916 ]] \n", 699 | "\n", 700 | "tvec: [[ 0.45090907]\n", 701 | " [-3.23939825]\n", 702 | " [ 3.29448184]]\n", 703 | "Average error of reprojecting points used to resect image 34 back onto it is: 1.680922767179613\n", 704 | "Fraction of Pnp inliers: 0.9704797047970479 num pts used in Pnp: 271\n", 705 | "Triangulating: 140 points.\n", 706 | "Average reprojection error for just-triangulated points on image 33 is: 0.6213353839252147 pixels.\n", 707 | "Average reprojection error for just-triangulated points on image 34 is: 0.6228455222598805 pixels.\n", 708 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 709 | " 0 1 1.5131e+04 3.70e+05 \n", 710 | " 1 3 1.1732e+04 3.40e+03 3.88e-01 1.27e+05 \n", 711 | " 2 4 9.6077e+03 2.12e+03 7.48e-01 4.23e+04 \n", 712 | " 3 6 9.5970e+03 1.08e+01 1.33e-01 6.53e+04 \n", 713 | "`ftol` termination condition is satisfied.\n", 714 | "Function evaluations 6, initial cost 1.5131e+04, final cost 9.5970e+03, first-order optimality 6.53e+04.\n", 715 | "Average reprojection error on image 22 is 0.3824692952428192 pixels\n", 716 | "Average reprojection error on image 21 is 0.19495101198163267 pixels\n", 717 | "Average reprojection error on image 20 is 0.268477757307908 pixels\n", 718 | "Average reprojection error on image 23 is 0.23618173767739783 pixels\n", 719 | "Average reprojection error on image 24 is 0.1725856220765769 pixels\n", 720 | "Average reprojection error on image 19 is 0.3254011900362519 pixels\n", 721 | "Average reprojection error on image 25 is 0.16345417959913294 pixels\n", 722 | "Average reprojection error on image 18 is 0.29321330021708564 pixels\n", 723 | "Average reprojection error on image 26 is 0.15575825755779704 pixels\n", 724 | "Average reprojection error on image 17 is 0.18790113516614038 pixels\n", 725 | "Average reprojection error on image 27 is 0.14113946184251636 pixels\n", 726 | "Average reprojection error on image 16 is 0.16006596322760536 pixels\n", 727 | "Average reprojection error on image 28 is 0.15739553956595315 pixels\n", 728 | "Average reprojection error on image 15 is 0.17701344738869246 pixels\n", 729 | "Average reprojection error on image 29 is 0.14741425597689378 pixels\n", 730 | "Average reprojection error on image 14 is 0.14486418967893355 pixels\n", 731 | "Average reprojection error on image 30 is 0.16379831772293507 pixels\n" 732 | ] 733 | }, 734 | { 735 | "name": "stdout", 736 | "output_type": "stream", 737 | "text": [ 738 | "Average reprojection error on image 13 is 0.15735045376321005 pixels\n", 739 | "Average reprojection error on image 31 is 0.1489785924633968 pixels\n", 740 | "Average reprojection error on image 12 is 0.16049501009035227 pixels\n", 741 | "Average reprojection error on image 32 is 0.14402683429523078 pixels\n", 742 | "Average reprojection error on image 11 is 0.11297105517077824 pixels\n", 743 | "Average reprojection error on image 33 is 0.12474588930162973 pixels\n", 744 | "Average reprojection error on image 10 is 0.11658161590516758 pixels\n", 745 | "Average reprojection error on image 34 is 0.29199178305972695 pixels\n", 746 | "Average reprojection error across all 25 resected images is 0.18916903585263056 pixels\n", 747 | "Unresected image: 9, resected: 10\n", 748 | "rvec: [[0.16231767]\n", 749 | " [2.02355744]\n", 750 | " [2.21527702]] \n", 751 | "\n", 752 | "tvec: [[0.44964469]\n", 753 | " [3.14570113]\n", 754 | " [2.95370165]]\n", 755 | "Average error of reprojecting points used to resect image 9 back onto it is: 0.36603166521965164\n", 756 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 133\n", 757 | "Triangulating: 107 points.\n", 758 | "Average reprojection error for just-triangulated points on image 9 is: 1.222628755116427 pixels.\n", 759 | "Average reprojection error for just-triangulated points on image 10 is: 9.679151237559 pixels.\n", 760 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 761 | " 0 1 2.6572e+04 8.50e+05 \n", 762 | " 1 2 1.4885e+04 1.17e+04 3.47e+00 9.55e+05 \n", 763 | "`ftol` termination condition is satisfied.\n", 764 | "Function evaluations 2, initial cost 2.6572e+04, final cost 1.4885e+04, first-order optimality 9.55e+05.\n", 765 | "Average reprojection error on image 22 is 0.38232181087033634 pixels\n", 766 | "Average reprojection error on image 21 is 0.193953525918906 pixels\n", 767 | "Average reprojection error on image 20 is 0.2657910565912789 pixels\n", 768 | "Average reprojection error on image 23 is 0.23595767324357025 pixels\n", 769 | "Average reprojection error on image 24 is 0.172648112308608 pixels\n", 770 | "Average reprojection error on image 19 is 0.32519026043145033 pixels\n", 771 | "Average reprojection error on image 25 is 0.16290589486290102 pixels\n", 772 | "Average reprojection error on image 18 is 0.29296263056989735 pixels\n", 773 | "Average reprojection error on image 26 is 0.1548549813239592 pixels\n", 774 | "Average reprojection error on image 17 is 0.18737456041656558 pixels\n", 775 | "Average reprojection error on image 27 is 0.13938707934288702 pixels\n", 776 | "Average reprojection error on image 16 is 0.15934262562003831 pixels\n", 777 | "Average reprojection error on image 28 is 0.15552212853305236 pixels\n", 778 | "Average reprojection error on image 15 is 0.17500191120050523 pixels\n", 779 | "Average reprojection error on image 29 is 0.144671843012863 pixels\n", 780 | "Average reprojection error on image 14 is 0.14056848609405118 pixels\n", 781 | "Average reprojection error on image 30 is 0.15710834661293854 pixels\n", 782 | "Average reprojection error on image 13 is 0.13939758615892694 pixels\n", 783 | "Average reprojection error on image 31 is 0.13468562077304252 pixels\n", 784 | "Average reprojection error on image 12 is 0.14178714995705266 pixels\n", 785 | "Average reprojection error on image 32 is 0.11675502650638588 pixels\n", 786 | "Average reprojection error on image 11 is 0.12330961741041171 pixels\n", 787 | "Average reprojection error on image 33 is 0.3427018410432979 pixels\n", 788 | "Average reprojection error on image 10 is 0.45695177971205425 pixels\n", 789 | "Average reprojection error on image 34 is 3.0206760850054293 pixels\n", 790 | "Average reprojection error on image 9 is 0.3632910916185761 pixels\n", 791 | "Average reprojection error across all 26 resected images is 0.3186584125053456 pixels\n", 792 | "Unresected image: 35, resected: 34\n", 793 | "rvec: [[-1.85968654]\n", 794 | " [ 0.03507201]\n", 795 | " [ 0.32400175]] \n", 796 | "\n", 797 | "tvec: [[ 0.58203708]\n", 798 | " [-3.09324325]\n", 799 | " [ 4.03379231]]\n", 800 | "Average error of reprojecting points used to resect image 35 back onto it is: 0.35603508768684083\n", 801 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 296\n", 802 | "Triangulating: 149 points.\n", 803 | "Average reprojection error for just-triangulated points on image 34 is: 6.524394093099689 pixels.\n", 804 | "Average reprojection error for just-triangulated points on image 35 is: 6.70343448662153 pixels.\n", 805 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 806 | " 0 1 3.3318e+04 1.92e+06 \n", 807 | " 1 2 9.8018e+03 2.35e+04 1.32e+00 1.26e+05 \n", 808 | "`ftol` termination condition is satisfied.\n", 809 | "Function evaluations 2, initial cost 3.3318e+04, final cost 9.8018e+03, first-order optimality 1.26e+05.\n", 810 | "Average reprojection error on image 22 is 0.3812722299172846 pixels\n", 811 | "Average reprojection error on image 21 is 0.19339270826388955 pixels\n", 812 | "Average reprojection error on image 20 is 0.26437459865498103 pixels\n", 813 | "Average reprojection error on image 23 is 0.23638880290807002 pixels\n", 814 | "Average reprojection error on image 24 is 0.1722030981721108 pixels\n", 815 | "Average reprojection error on image 19 is 0.32522868589905785 pixels\n", 816 | "Average reprojection error on image 25 is 0.1624890076487987 pixels\n", 817 | "Average reprojection error on image 18 is 0.29322918549964716 pixels\n", 818 | "Average reprojection error on image 26 is 0.1559059161881221 pixels\n", 819 | "Average reprojection error on image 17 is 0.18747542961186167 pixels\n", 820 | "Average reprojection error on image 27 is 0.14123736964680544 pixels\n", 821 | "Average reprojection error on image 16 is 0.15923498904679825 pixels\n", 822 | "Average reprojection error on image 28 is 0.15743729508243723 pixels\n", 823 | "Average reprojection error on image 15 is 0.17496215984868135 pixels\n", 824 | "Average reprojection error on image 29 is 0.14675077986548965 pixels\n", 825 | "Average reprojection error on image 14 is 0.14058275112854354 pixels\n", 826 | "Average reprojection error on image 30 is 0.16184468937953214 pixels\n", 827 | "Average reprojection error on image 13 is 0.13923675835878271 pixels\n", 828 | "Average reprojection error on image 31 is 0.14282322416501053 pixels\n", 829 | "Average reprojection error on image 12 is 0.1407760883854536 pixels\n", 830 | "Average reprojection error on image 32 is 0.12136039183624062 pixels\n", 831 | "Average reprojection error on image 11 is 0.11543124951643913 pixels\n", 832 | "Average reprojection error on image 33 is 0.1121976852448596 pixels\n", 833 | "Average reprojection error on image 10 is 0.11753500854006768 pixels\n", 834 | "Average reprojection error on image 34 is 0.2269006845392072 pixels\n", 835 | "Average reprojection error on image 9 is 0.11589567031838174 pixels\n", 836 | "Average reprojection error on image 35 is 0.4906039046353483 pixels\n", 837 | "Average reprojection error across all 27 resected images is 0.1917322356408111 pixels\n", 838 | "Unresected image: 8, resected: 9\n", 839 | "rvec: [[ 1.62841645]\n", 840 | " [-0.01361358]\n", 841 | " [-0.24138299]] \n", 842 | "\n", 843 | "tvec: [[0.44292501]\n", 844 | " [3.14748134]\n", 845 | " [3.43023116]]\n", 846 | "Average error of reprojecting points used to resect image 8 back onto it is: 1.2639744029126183\n", 847 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 149\n", 848 | "Triangulating: 157 points.\n", 849 | "Average reprojection error for just-triangulated points on image 8 is: 1.4129310633507646 pixels.\n", 850 | "Average reprojection error for just-triangulated points on image 9 is: 15.297754297119939 pixels.\n", 851 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 852 | " 0 1 6.9789e+04 1.83e+06 \n", 853 | " 1 2 1.0539e+04 5.93e+04 5.83e+00 2.49e+05 \n", 854 | " 2 3 9.6427e+03 8.96e+02 5.01e-01 8.97e+03 \n", 855 | "`ftol` termination condition is satisfied.\n", 856 | "Function evaluations 3, initial cost 6.9789e+04, final cost 9.6427e+03, first-order optimality 8.97e+03.\n", 857 | "Average reprojection error on image 22 is 0.3812864511435987 pixels\n", 858 | "Average reprojection error on image 21 is 0.19339335362957502 pixels\n", 859 | "Average reprojection error on image 20 is 0.2631688260995267 pixels\n", 860 | "Average reprojection error on image 23 is 0.23621583276714392 pixels\n", 861 | "Average reprojection error on image 24 is 0.17212609139168583 pixels\n", 862 | "Average reprojection error on image 19 is 0.3256081334102725 pixels\n", 863 | "Average reprojection error on image 25 is 0.1628129609437705 pixels\n", 864 | "Average reprojection error on image 18 is 0.2935893784139251 pixels\n", 865 | "Average reprojection error on image 26 is 0.15618741298477462 pixels\n", 866 | "Average reprojection error on image 17 is 0.18766553116800755 pixels\n", 867 | "Average reprojection error on image 27 is 0.1413768508391311 pixels\n", 868 | "Average reprojection error on image 16 is 0.15954237634650015 pixels\n", 869 | "Average reprojection error on image 28 is 0.1570323570278647 pixels\n", 870 | "Average reprojection error on image 15 is 0.17524519707343336 pixels\n", 871 | "Average reprojection error on image 29 is 0.14681641967353926 pixels\n", 872 | "Average reprojection error on image 14 is 0.14371175358142863 pixels\n" 873 | ] 874 | }, 875 | { 876 | "name": "stdout", 877 | "output_type": "stream", 878 | "text": [ 879 | "Average reprojection error on image 30 is 0.16120404407319594 pixels\n", 880 | "Average reprojection error on image 13 is 0.14099490882817806 pixels\n", 881 | "Average reprojection error on image 31 is 0.14194798191983646 pixels\n", 882 | "Average reprojection error on image 12 is 0.14627303099199573 pixels\n", 883 | "Average reprojection error on image 32 is 0.12073153268654024 pixels\n", 884 | "Average reprojection error on image 11 is 0.1227992299403102 pixels\n", 885 | "Average reprojection error on image 33 is 0.11013150946542494 pixels\n", 886 | "Average reprojection error on image 10 is 0.1396662934923137 pixels\n", 887 | "Average reprojection error on image 34 is 0.09957671833746498 pixels\n", 888 | "Average reprojection error on image 9 is 0.10314665958180447 pixels\n", 889 | "Average reprojection error on image 35 is 0.1267859071245942 pixels\n", 890 | "Average reprojection error on image 8 is 0.136220821482865 pixels\n", 891 | "Average reprojection error across all 28 resected images is 0.17304491301495362 pixels\n", 892 | "Unresected image: 36, resected: 35\n", 893 | "rvec: [[-1.93865076]\n", 894 | " [ 0.01456945]\n", 895 | " [ 0.3077692 ]] \n", 896 | "\n", 897 | "tvec: [[ 0.70086145]\n", 898 | " [-2.98313399]\n", 899 | " [ 4.29855446]]\n", 900 | "Average error of reprojecting points used to resect image 36 back onto it is: 1.2157546675421844\n", 901 | "Fraction of Pnp inliers: 0.9937888198757764 num pts used in Pnp: 322\n", 902 | "Triangulating: 143 points.\n", 903 | "Average reprojection error for just-triangulated points on image 35 is: 10.714102008497148 pixels.\n", 904 | "Average reprojection error for just-triangulated points on image 36 is: 7.311287044064802 pixels.\n", 905 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 906 | " 0 1 5.2931e+04 1.33e+06 \n", 907 | " 1 2 1.5967e+04 3.70e+04 2.42e+00 1.09e+06 \n", 908 | "`ftol` termination condition is satisfied.\n", 909 | "Function evaluations 2, initial cost 5.2931e+04, final cost 1.5967e+04, first-order optimality 1.09e+06.\n", 910 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 911 | " 0 1 1.5967e+04 1.09e+06 \n", 912 | " 1 2 1.0071e+04 5.90e+03 9.86e-01 1.22e+04 \n", 913 | " 2 3 1.0003e+04 6.75e+01 3.57e-01 1.11e+04 \n", 914 | "`ftol` termination condition is satisfied.\n", 915 | "Function evaluations 3, initial cost 1.5967e+04, final cost 1.0003e+04, first-order optimality 1.11e+04.\n", 916 | "Average reprojection error on image 22 is 0.3810261205170952 pixels\n", 917 | "Average reprojection error on image 21 is 0.1929334222532848 pixels\n", 918 | "Average reprojection error on image 20 is 0.26140818554799444 pixels\n", 919 | "Average reprojection error on image 23 is 0.23616249122695782 pixels\n", 920 | "Average reprojection error on image 24 is 0.1720285433891494 pixels\n", 921 | "Average reprojection error on image 19 is 0.325642559959216 pixels\n", 922 | "Average reprojection error on image 25 is 0.1625927477542533 pixels\n", 923 | "Average reprojection error on image 18 is 0.29356113401989226 pixels\n", 924 | "Average reprojection error on image 26 is 0.15643092905113376 pixels\n", 925 | "Average reprojection error on image 17 is 0.1874725143837101 pixels\n", 926 | "Average reprojection error on image 27 is 0.14239398608936193 pixels\n", 927 | "Average reprojection error on image 16 is 0.1591971592926707 pixels\n", 928 | "Average reprojection error on image 28 is 0.15884494405742527 pixels\n", 929 | "Average reprojection error on image 15 is 0.1750962226593357 pixels\n", 930 | "Average reprojection error on image 29 is 0.1490887100727287 pixels\n", 931 | "Average reprojection error on image 14 is 0.14312678994913855 pixels\n", 932 | "Average reprojection error on image 30 is 0.16429009454930066 pixels\n", 933 | "Average reprojection error on image 13 is 0.14061053268242674 pixels\n", 934 | "Average reprojection error on image 31 is 0.14855194581684608 pixels\n", 935 | "Average reprojection error on image 12 is 0.1463348547725874 pixels\n", 936 | "Average reprojection error on image 32 is 0.12880969665823822 pixels\n", 937 | "Average reprojection error on image 11 is 0.1227204742103847 pixels\n", 938 | "Average reprojection error on image 33 is 0.1287219316974244 pixels\n", 939 | "Average reprojection error on image 10 is 0.139449497865321 pixels\n", 940 | "Average reprojection error on image 34 is 0.14957165022869257 pixels\n", 941 | "Average reprojection error on image 9 is 0.09951812502721763 pixels\n", 942 | "Average reprojection error on image 35 is 0.32284591430774795 pixels\n", 943 | "Average reprojection error on image 8 is 0.10868451205486244 pixels\n", 944 | "Average reprojection error on image 36 is 0.3302748674111518 pixels\n", 945 | "Average reprojection error across all 29 resected images is 0.18715139853467413 pixels\n", 946 | "Unresected image: 7, resected: 8\n", 947 | "rvec: [[ 1.69689671]\n", 948 | " [-0.00907849]\n", 949 | " [-0.25784727]] \n", 950 | "\n", 951 | "tvec: [[0.54150648]\n", 952 | " [3.16307834]\n", 953 | " [3.60394796]]\n", 954 | "Average error of reprojecting points used to resect image 7 back onto it is: 0.3500322449234162\n", 955 | "Fraction of Pnp inliers: 1.0 num pts used in Pnp: 234\n", 956 | "Triangulating: 243 points.\n", 957 | "Average reprojection error for just-triangulated points on image 7 is: 22.94070173618651 pixels.\n", 958 | "Average reprojection error for just-triangulated points on image 8 is: 105.49318476430507 pixels.\n", 959 | " Iteration Total nfev Cost Cost reduction Step norm Optimality \n", 960 | " 0 1 3.9651e+06 4.94e+07 \n", 961 | " 1 2 4.5281e+05 3.51e+06 6.92e+00 1.18e+07 \n", 962 | " 2 3 6.2385e+04 3.90e+05 1.54e+01 2.35e+06 \n", 963 | " 3 4 1.0763e+04 5.16e+04 7.30e+00 2.19e+05 \n", 964 | " 4 5 1.0115e+04 6.48e+02 3.38e-01 3.31e+03 \n", 965 | "`ftol` termination condition is satisfied.\n", 966 | "Function evaluations 5, initial cost 3.9651e+06, final cost 1.0115e+04, first-order optimality 3.31e+03.\n", 967 | "Average reprojection error on image 22 is 0.3790215837739872 pixels\n", 968 | "Average reprojection error on image 21 is 0.19148355293860925 pixels\n", 969 | "Average reprojection error on image 20 is 0.25169460367106017 pixels\n", 970 | "Average reprojection error on image 23 is 0.23490509130074005 pixels\n", 971 | "Average reprojection error on image 24 is 0.17232626522770708 pixels\n", 972 | "Average reprojection error on image 19 is 0.3275647758634737 pixels\n", 973 | "Average reprojection error on image 25 is 0.16260810210306864 pixels\n", 974 | "Average reprojection error on image 18 is 0.29500774615951203 pixels\n", 975 | "Average reprojection error on image 26 is 0.1561563802175959 pixels\n", 976 | "Average reprojection error on image 17 is 0.1880293621632955 pixels\n", 977 | "Average reprojection error on image 27 is 0.14214179410124456 pixels\n", 978 | "Average reprojection error on image 16 is 0.1589189449265632 pixels\n", 979 | "Average reprojection error on image 28 is 0.1587268236908216 pixels\n", 980 | "Average reprojection error on image 15 is 0.1749285195682732 pixels\n", 981 | "Average reprojection error on image 29 is 0.1489939534584021 pixels\n", 982 | "Average reprojection error on image 14 is 0.14400373015081142 pixels\n", 983 | "Average reprojection error on image 30 is 0.16422268669501183 pixels\n", 984 | "Average reprojection error on image 13 is 0.14134608119919542 pixels\n", 985 | "Average reprojection error on image 31 is 0.14849898119055077 pixels\n", 986 | "Average reprojection error on image 12 is 0.14914103656700944 pixels\n", 987 | "Average reprojection error on image 32 is 0.12868403971152612 pixels\n", 988 | "Average reprojection error on image 11 is 0.12765883477057005 pixels\n", 989 | "Average reprojection error on image 33 is 0.12736935299961852 pixels\n", 990 | "Average reprojection error on image 10 is 0.1523782749248624 pixels\n", 991 | "Average reprojection error on image 34 is 0.14107200609192924 pixels\n", 992 | "Average reprojection error on image 9 is 0.12405853584833706 pixels\n", 993 | "Average reprojection error on image 35 is 0.31547538871930436 pixels\n", 994 | "Average reprojection error on image 8 is 0.11983368407365605 pixels\n", 995 | "Average reprojection error on image 36 is 0.33739633133695 pixels\n", 996 | "Average reprojection error on image 7 is 0.1369497321712683 pixels\n", 997 | "Average reprojection error across all 30 resected images is 0.1866865398538318 pixels\n" 998 | ] 999 | } 1000 | ], 1001 | "source": [ 1002 | "### This cell grows and refines the reconstruction \n", 1003 | "BA_chkpts = [3,4,5,6] + [int(6*(1.34**i)) for i in range(25)]\n", 1004 | "while len(unresected_imgs) > 0:\n", 1005 | " resected_idx, unresected_idx, prepend = r.next_img_pair_to_grow_reconstruction(n_imgs, best_pair, resected_imgs, unresected_imgs, img_adjacency)\n", 1006 | " points3d_with_views, pts3d_for_pnp, pts2d_for_pnp, triangulation_status = r.get_correspondences_for_pnp(resected_idx, unresected_idx, points3d_with_views, matches, keypoints)\n", 1007 | " if len(pts3d_for_pnp) < 12:\n", 1008 | " print(f\"{len(pts3d_for_pnp)} is too few correspondences for pnp. Skipping imgs resected:{resected_idx} and unresected:{unresected_idx}\")\n", 1009 | " print(f\"Currently resected imgs: {resected_imgs}, unresected: {unresected_imgs}\")\n", 1010 | " continue\n", 1011 | "\n", 1012 | " R_res = R_mats[resected_idx]\n", 1013 | " t_res = t_vecs[resected_idx]\n", 1014 | " print(f\"Unresected image: {unresected_idx}, resected: {resected_idx}\")\n", 1015 | " R_new, t_new = r.do_pnp(pts3d_for_pnp, pts2d_for_pnp, K)\n", 1016 | " R_mats[unresected_idx] = R_new\n", 1017 | " t_vecs[unresected_idx] = t_new\n", 1018 | " if prepend == True: resected_imgs.insert(0, unresected_idx)\n", 1019 | " else: resected_imgs.append(unresected_idx)\n", 1020 | " unresected_imgs.remove(unresected_idx)\n", 1021 | " pnp_errors, projpts, avg_err, perc_inliers = r.test_reproj_pnp_points(pts3d_for_pnp, pts2d_for_pnp, R_new, t_new, K)\n", 1022 | " print(f\"Average error of reprojecting points used to resect image {unresected_idx} back onto it is: {avg_err}\")\n", 1023 | " print(f\"Fraction of Pnp inliers: {perc_inliers} num pts used in Pnp: {len(pnp_errors)}\")\n", 1024 | " \n", 1025 | " if resected_idx < unresected_idx:\n", 1026 | " kpts1, kpts2, kpts1_idxs, kpts2_idxs = r.get_aligned_kpts(resected_idx, unresected_idx, keypoints, matches, mask=triangulation_status)\n", 1027 | " if np.sum(triangulation_status) > 0: #at least 1 point needs to be triangulated\n", 1028 | " points3d_with_views, tri_errors, avg_tri_err_l, avg_tri_err_r = r.triangulate_points_and_reproject(R_res, t_res, R_new, t_new, K, points3d_with_views, resected_idx, unresected_idx, kpts1, kpts2, kpts1_idxs, kpts2_idxs, reproject=True)\n", 1029 | " else:\n", 1030 | " kpts1, kpts2, kpts1_idxs, kpts2_idxs = r.get_aligned_kpts(unresected_idx, resected_idx, keypoints, matches, mask=triangulation_status)\n", 1031 | " if np.sum(triangulation_status) > 0: #at least 1 point needs to be triangulated\n", 1032 | " points3d_with_views, tri_errors, avg_tri_err_l, avg_tri_err_r = r.triangulate_points_and_reproject(R_new, t_new, R_res, t_res, K, points3d_with_views, unresected_idx, resected_idx, kpts1, kpts2, kpts1_idxs, kpts2_idxs, reproject=True)\n", 1033 | " \n", 1034 | " if 0.8 < perc_inliers < 0.95 or 5 < avg_tri_err_l < 10 or 5 < avg_tri_err_r < 10: \n", 1035 | " #If % of inlers from Pnp is too low or triangulation error on either image is too high, bundle adjust\n", 1036 | " points3d_with_views, R_mats, t_vecs = b.do_BA(points3d_with_views, R_mats, t_vecs, resected_imgs, keypoints, K, ftol=1e0)\n", 1037 | " \n", 1038 | " if len(resected_imgs) in BA_chkpts or len(unresected_imgs) == 0 or perc_inliers <= 0.8 or avg_tri_err_l >= 10 or avg_tri_err_r >= 10:\n", 1039 | " #If % of inlers from Pnp is very low or triangulation error on either image is very high, bundle adjust with stricter tolerance\n", 1040 | " points3d_with_views, R_mats, t_vecs = b.do_BA(points3d_with_views, R_mats, t_vecs, resected_imgs, keypoints, K, ftol=1e-1)\n", 1041 | " \n", 1042 | " av = 0\n", 1043 | " for im in resected_imgs:\n", 1044 | " p3d, p2d, avg_error, errors = r.get_reproj_errors(im, points3d_with_views, R_mats[im], t_vecs[im], K, keypoints, distCoeffs=np.array([]))\n", 1045 | " print(f'Average reprojection error on image {im} is {avg_error} pixels')\n", 1046 | " av += avg_error\n", 1047 | " av = av/len(resected_imgs)\n", 1048 | " print(f'Average reprojection error across all {len(resected_imgs)} resected images is {av} pixels')" 1049 | ] 1050 | }, 1051 | { 1052 | "cell_type": "code", 1053 | "execution_count": 16, 1054 | "metadata": {}, 1055 | "outputs": [ 1056 | { 1057 | "data": { 1058 | "text/html": [ 1059 | "\n", 1060 | " \n", 1067 | " " 1068 | ], 1069 | "text/plain": [ 1070 | "" 1071 | ] 1072 | }, 1073 | "execution_count": 16, 1074 | "metadata": {}, 1075 | "output_type": "execute_result" 1076 | } 1077 | ], 1078 | "source": [ 1079 | "### This cell visualizes the pointcloud\n", 1080 | "num_voxels = 200 #Set to 100 for faster visualization, 200 for higher resolution.\n", 1081 | "x, y, z = [], [], []\n", 1082 | "for pt3 in points3d_with_views:\n", 1083 | " if abs(pt3.point3d[0][0]) + abs(pt3.point3d[0][1]) + abs(pt3.point3d[0][2]) < 100:\n", 1084 | " x.append(pt3.point3d[0][0])\n", 1085 | " y.append(pt3.point3d[0][1])\n", 1086 | " z.append(pt3.point3d[0][2])\n", 1087 | "vpoints = list(zip(x,y,z))\n", 1088 | "vpoints = np.array(vpoints)\n", 1089 | "vpoints_df = pd.DataFrame(data=vpoints, index=[f\"{i}\" for i in range(vpoints.shape[0])], columns=[\"x\", \"y\",\"z\"])\n", 1090 | "cloud = pyntcloud.PyntCloud(vpoints_df)\n", 1091 | "cloud.add_structure('voxelgrid', n_x=num_voxels,n_y=num_voxels,n_z=num_voxels)\n", 1092 | "cloud.structures[f'V([{num_voxels}, {num_voxels}, {num_voxels}],[None, None, None],True)'].plot(d=3)" 1093 | ] 1094 | }, 1095 | { 1096 | "cell_type": "code", 1097 | "execution_count": null, 1098 | "metadata": {}, 1099 | "outputs": [], 1100 | "source": [] 1101 | } 1102 | ], 1103 | "metadata": { 1104 | "kernelspec": { 1105 | "display_name": "Python 3", 1106 | "language": "python", 1107 | "name": "python3" 1108 | }, 1109 | "language_info": { 1110 | "codemirror_mode": { 1111 | "name": "ipython", 1112 | "version": 3 1113 | }, 1114 | "file_extension": ".py", 1115 | "mimetype": "text/x-python", 1116 | "name": "python", 1117 | "nbconvert_exporter": "python", 1118 | "pygments_lexer": "ipython3", 1119 | "version": "3.6.10" 1120 | } 1121 | }, 1122 | "nbformat": 4, 1123 | "nbformat_minor": 2 1124 | } 1125 | -------------------------------------------------------------------------------- /matching.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | def find_features(n_imgs, imgset): 5 | """ 6 | Reads in n_imgs images from a directory and returns lists of keypoints and 7 | descriptors each of dimensions (n_imgs x n_kpts). 8 | 9 | :param n_imgs: Number of images to read in and process. 10 | :param imgset: String. Name of image set to read in and get matches/keypoints for 11 | """ 12 | images = [] 13 | keypoints = [] 14 | descriptors = [] 15 | sift = cv2.xfeatures2d.SIFT_create() 16 | for i in range(n_imgs): 17 | if imgset == 'templering': 18 | img = cv2.imread(f'./datasets/templeRing/{i:02d}.png', cv2.IMREAD_GRAYSCALE) 19 | K = np.matrix('1520.40 0.00 302.32; 0.00 1525.90 246.87; 0.00 0.00 1.00') 20 | elif imgset == 'Viking': 21 | img = cv2.imread(f'./datasets/Viking/{i:02d}.jpg', cv2.IMREAD_GRAYSCALE) 22 | K = np.matrix('523.81 0.00 252.00; 0.00 523.81 336.00; 0.00 0.00 1.00') 23 | else: raise ValueError('Need to pass in valid imgset name!') 24 | images.append(img) 25 | kp, des = sift.detectAndCompute(images[-1], None) 26 | keypoints.append(kp) 27 | descriptors.append(des) 28 | return images, keypoints, descriptors, K 29 | 30 | def find_matches(matcher, keypoints, descriptors, lowes_ratio=0.7): 31 | """ 32 | Performs kNN matching with k=2 and Lowes' ratio test to return a list of dimensions 33 | n_imgs x n_imgs where matches[i][j] is the list of cv2.DMatch objects for images i and j 34 | 35 | :param matcher: Either a cv2.FlannBasedMatcher or cv2.BFMatcher 36 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 37 | :param descriptors: List of lists of 128 dim lists (for SIFT). descriptors[i] is list for image i. 38 | """ 39 | matches = [] 40 | n_imgs = len(keypoints) 41 | for i in range(n_imgs): 42 | matches.append([]) 43 | for j in range(n_imgs): 44 | if j <= i: matches[i].append(None) 45 | else: 46 | match = [] 47 | m = matcher.knnMatch(descriptors[i], descriptors[j], k=2) 48 | for k in range(len(m)): 49 | try: 50 | if m[k][0].distance < lowes_ratio*m[k][1].distance: 51 | match.append(m[k][0]) 52 | except: 53 | continue 54 | matches[i].append(match) 55 | return matches 56 | 57 | 58 | def remove_outliers(matches, keypoints): 59 | """ 60 | Calculate fundamental matrix between 2 images to remove incorrect matches. 61 | Return matches with outlier removed. Rejects matches between images if there are < 20 62 | 63 | :param matches: List of lists of lists where matches[i][j][k] is the kth cv2.Dmatch object for images i and j 64 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 65 | """ 66 | 67 | for i in range(len(matches)): 68 | for j in range(len(matches[i])): 69 | if j <= i: continue 70 | if len(matches[i][j]) < 20: 71 | matches[i][j] = [] 72 | continue 73 | kpts_i = [] 74 | kpts_j = [] 75 | for k in range(len(matches[i][j])): 76 | kpts_i.append(keypoints[i][matches[i][j][k].queryIdx].pt) 77 | kpts_j.append(keypoints[j][matches[i][j][k].trainIdx].pt) 78 | kpts_i = np.int32(kpts_i) 79 | kpts_j = np.int32(kpts_j) 80 | F, mask = cv2.findFundamentalMat(kpts_i, kpts_j, cv2.FM_RANSAC, ransacReprojThreshold=3) 81 | if np.linalg.det(F) > 1e-7: raise ValueError(f"Bad F_mat between images: {i}, {j}. Determinant: {np.linalg.det(F)}") 82 | matches[i][j] = np.array(matches[i][j]) 83 | if mask is None: 84 | matches[i][j] = [] 85 | continue 86 | matches[i][j] = matches[i][j][mask.ravel() == 1] 87 | matches[i][j] = list(matches[i][j]) 88 | 89 | if len(matches[i][j]) < 20: 90 | matches[i][j] = [] 91 | continue 92 | 93 | return matches 94 | 95 | def num_matches(matches): 96 | """ Used for debugging. Count matches before/after outlier removal """ 97 | n_matches = 0 98 | for i in range(len(matches)): 99 | for j in range(len(matches[i])): 100 | if j <= i: continue 101 | n_matches += len(matches[i][j]) 102 | 103 | return n_matches 104 | 105 | def print_num_img_pairs(matches): 106 | num_img_pairs = 0 107 | num_pairs = 0 108 | for i in range(len(matches)): 109 | for j in range(len(matches[i])): 110 | if j <= i: continue 111 | num_pairs += 1 112 | if len(matches[i][j]) > 0: num_img_pairs += 1 113 | 114 | print(f"Number of img pairs is {num_img_pairs} out of possible {num_pairs}") 115 | 116 | def create_img_adjacency_matrix(n_imgs, matches): 117 | """ 118 | Returns a n_imgs x n_imgs matrix where if img_adjacency[i][j] = 1, the images[i] and images[j] 119 | have a sufficient number of matches, and are regarded as viewing the same scene. 120 | 121 | :param n_imgs: Integer. Total number of images to be used in reconstruction 122 | :param matches: List of lists of lists where matches[i][j][k] is the kth cv2.Dmatch object for images i and j 123 | """ 124 | num_img_pairs = 0 125 | num_pairs = 0 126 | pairs = [] 127 | img_adjacency = np.zeros((n_imgs, n_imgs)) 128 | for i in range(len(matches)): 129 | for j in range(len(matches[i])): 130 | if j <= i: continue 131 | num_pairs += 1 132 | if len(matches[i][j]) > 0: 133 | num_img_pairs += 1 134 | pairs.append((i,j)) 135 | img_adjacency[i][j] = 1 136 | 137 | list_of_img_pairs = pairs 138 | return img_adjacency, list_of_img_pairs 139 | -------------------------------------------------------------------------------- /reconstruction.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | import cv2 4 | 5 | class Point3D_with_views: 6 | """If img_x is a key and kpt_y is a value in source_2dpt_idxs dict, then the 3d point in self.point3d 7 | corresponds to the 2d point keypoints[img_x][kpt_y] (and to any other pairs in the dict)""" 8 | def __init__(self, point3d, source_2dpt_idxs): 9 | self.point3d = point3d 10 | self.source_2dpt_idxs = source_2dpt_idxs 11 | 12 | def best_img_pair(img_adjacency, matches, keypoints, K, top_x_perc=0.2): 13 | """ 14 | Returns the image pair that has the greatest difference in rotation given that it is in the 15 | top xth percentile for number of matches between images. Intent is to have a stable baseline to 16 | initialize the reconstruction. 17 | 18 | :param img_adjacency: Matrix with value at indices i and j = 1 if images have matches, else 0 19 | :param matches: List of lists of lists where matches[i][j][k] is the kth cv2.Dmatch object for images i and j 20 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 21 | :param K: Matrix. Intrinsic parameters of camera 22 | :param top_x_perc: Float. Threshold for considering image pairs to init reconstruction. e.g 0.2 means top 20% 23 | of img pairs by num_matches 24 | """ 25 | num_matches = [] 26 | 27 | for i in range(img_adjacency.shape[0]): 28 | for j in range(img_adjacency.shape[1]): 29 | if img_adjacency[i][j] == 1: 30 | num_matches.append(len(matches[i][j])) 31 | 32 | num_matches = sorted(num_matches, reverse=True) 33 | min_match_idx = int(len(num_matches)*top_x_perc) 34 | min_matches = num_matches[min_match_idx] 35 | best_R = 0 36 | best_pair = None 37 | 38 | #For all img pairs in top xth %ile of matches, find pair with greatest rotation between images. 39 | for i in range(img_adjacency.shape[0]): 40 | for j in range(img_adjacency.shape[1]): 41 | if img_adjacency[i][j] == 1: 42 | if len(matches[i][j]) > min_matches: 43 | kpts_i, kpts_j, kpts_i_idxs, kpts_j_idxs = get_aligned_kpts(i, j, keypoints, matches) 44 | E, _ = cv2.findEssentialMat(kpts_i, kpts_j, K, cv2.FM_RANSAC, 0.999, 1.0) 45 | points, R1, t1, mask = cv2.recoverPose(E, kpts_i, kpts_j, K) 46 | rvec, _ = cv2.Rodrigues(R1) 47 | rot_angle = abs(rvec[0]) +abs(rvec[1]) + abs(rvec[2])# sum rotation angles for each dimension 48 | if (rot_angle > best_R or best_pair == None) and points == len(kpts_i): #Ensure recoverPose worked. 49 | best_R = rot_angle 50 | best_pair = (i,j) 51 | 52 | return best_pair 53 | 54 | def get_aligned_kpts(i, j, keypoints, matches, mask=None): 55 | """ 56 | Returns list of kpts where kpts_i[ind] and kpts_j[ind] are pixel coords of matching kpts, and 57 | lists of indices of each keypoint in kpts_i and kpts_j. This information then used for Essential matrix 58 | calculation and/or triangulation. 59 | 60 | :param i: Integer. Index of first image 61 | :param j: Integer. Index of second image 62 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 63 | :param matches: List of lists of lists where matches[i][j][k] is the kth cv2.Dmatch object for images i and j 64 | :param mask: Array. Equal to 0 at indices where information on that keypoint is not needed, else 1 65 | """ 66 | if mask is None: 67 | mask = np.ones(len(matches[i][j])) #if no mask is given, all matches used. This is helpful if we only want to triangulate certain matches. 68 | 69 | kpts_i, kpts_i_idxs, kpts_j, kpts_j_idxs = [], [], [], [] 70 | for k in range(len(matches[i][j])): 71 | if mask[k] == 0: continue 72 | kpts_i.append(keypoints[i][matches[i][j][k].queryIdx].pt) 73 | kpts_i_idxs.append(matches[i][j][k].queryIdx) 74 | kpts_j.append(keypoints[j][matches[i][j][k].trainIdx].pt) 75 | kpts_j_idxs.append(matches[i][j][k].trainIdx) 76 | kpts_i = np.array(kpts_i) 77 | kpts_j = np.array(kpts_j) 78 | kpts_i = np.expand_dims(kpts_i, axis=1) #this seems to be required for cv2.undistortPoints and cv2.trangulatePoints to work 79 | kpts_j = np.expand_dims(kpts_j, axis=1) 80 | 81 | return kpts_i, kpts_j, kpts_i_idxs, kpts_j_idxs 82 | 83 | def triangulate_points_and_reproject(R_l, t_l, R_r, t_r, K, points3d_with_views, img_idx1, img_idx2, kpts_i, kpts_j, kpts_i_idxs, kpts_j_idxs, reproject=True): 84 | """ 85 | Triangulate points given 2D correspondences as well as camera parameters. 86 | 87 | :param R_l: Rotation matrix for left image 88 | :param t_l: Translation vector for left image 89 | :param R_r: Rotation matrix for right image 90 | :param t_r: Translation vector for right image 91 | :param K: Intrinsics matrix 92 | :param points3d_with_views: List of Point3D_with_views objects. Will have new points appended to it 93 | :param img_idx1: Index of left image 94 | :param img_idx2: Index of right image 95 | :param kpts_i: List of index-aligned keypoint coordinates in left image 96 | :param kpts_j: List of index-aligned keypoint coordinates in right image 97 | :param kpts_i_idxs: Indexes of keypoints for left image 98 | :param kpts_j_idxs: Indexes of keypoints for right image 99 | :param reproject: Boolean. True if reprojection errors desired 100 | """ 101 | 102 | print(f"Triangulating: {len(kpts_i)} points.") 103 | P_l = np.dot(K, np.hstack((R_l, t_l))) 104 | P_r = np.dot(K, np.hstack((R_r, t_r))) 105 | 106 | kpts_i = np.squeeze(kpts_i) 107 | kpts_i = kpts_i.transpose() 108 | kpts_i = kpts_i.reshape(2,-1) 109 | kpts_j = np.squeeze(kpts_j) 110 | kpts_j = kpts_j.transpose() 111 | kpts_j = kpts_j.reshape(2,-1) 112 | 113 | point_4d_hom = cv2.triangulatePoints(P_l, P_r, kpts_i, kpts_j) 114 | points_3D = cv2.convertPointsFromHomogeneous(point_4d_hom.transpose()) 115 | for i in range(kpts_i.shape[1]): 116 | source_2dpt_idxs = {img_idx1:kpts_i_idxs[i], img_idx2:kpts_j_idxs[i]} 117 | pt = Point3D_with_views(points_3D[i], source_2dpt_idxs) 118 | points3d_with_views.append(pt) 119 | 120 | if reproject: 121 | kpts_i = kpts_i.transpose() 122 | kpts_j = kpts_j.transpose() 123 | rvec_l, _ = cv2.Rodrigues(R_l) 124 | rvec_r, _ = cv2.Rodrigues(R_r) 125 | projPoints_l, _ = cv2.projectPoints(points_3D, rvec_l, t_l, K, distCoeffs=np.array([])) 126 | projPoints_r, _ = cv2.projectPoints(points_3D, rvec_r, t_r, K, distCoeffs=np.array([])) 127 | delta_l , delta_r = [], [] 128 | for i in range(len(projPoints_l)): 129 | delta_l.append(abs(projPoints_l[i][0][0] - kpts_i[i][0])) 130 | delta_l.append(abs(projPoints_l[i][0][1] - kpts_i[i][1])) 131 | delta_r.append(abs(projPoints_r[i][0][0] - kpts_j[i][0])) 132 | delta_r.append(abs(projPoints_r[i][0][1] - kpts_j[i][1])) 133 | avg_error_l = sum(delta_l)/len(delta_l) 134 | avg_error_r = sum(delta_r)/len(delta_r) 135 | print(f"Average reprojection error for just-triangulated points on image {img_idx1} is:", avg_error_l, "pixels.") 136 | print(f"Average reprojection error for just-triangulated points on image {img_idx2} is:", avg_error_r, "pixels.") 137 | errors = list(zip(delta_l, delta_r)) 138 | return points3d_with_views, errors, avg_error_l, avg_error_r 139 | 140 | return points3d_with_views 141 | 142 | def initialize_reconstruction(keypoints, matches, K, img_idx1, img_idx2): 143 | """ 144 | Solve for pose of initial image pair and triangulate points seen by them. 145 | 146 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 147 | :param matches: List of lists of lists where matches[i][j][k] is the kth cv2.Dmatch object for images i and j 148 | :param K: Intrinsics matrix 149 | :param img_idx1: Index of left image 150 | :param img_idx2: Index of right image 151 | """ 152 | kpts_i, kpts_j, kpts_i_idxs, kpts_j_idxs = get_aligned_kpts(img_idx1, img_idx2, keypoints, matches) 153 | E, _ = cv2.findEssentialMat(kpts_i, kpts_j, K, cv2.FM_RANSAC, 0.999, 1.0) 154 | points, R1, t1, mask = cv2.recoverPose(E, kpts_i, kpts_j, K) 155 | assert abs(np.linalg.det(R1)) - 1 < 1e-7 156 | 157 | R0 = np.eye(3, 3) 158 | t0 = np.zeros((3, 1)) 159 | 160 | points3d_with_views = [] 161 | points3d_with_views = triangulate_points_and_reproject( 162 | R0, t0, R1, t1, K, points3d_with_views, img_idx1, img_idx2, kpts_i, kpts_j, kpts_i_idxs, kpts_j_idxs, reproject=False) 163 | 164 | return R0, t0, R1, t1, points3d_with_views 165 | 166 | def get_idxs_in_correct_order(idx1, idx2): 167 | """First idx must be smaller than second when using upper-triangular arrays (matches, keypoints)""" 168 | if idx1 < idx2: return idx1, idx2 169 | else: return idx2, idx1 170 | 171 | def images_adjacent(i, j, img_adjacency): 172 | """Return true if both images view the same scene (have enough matches).""" 173 | if img_adjacency[i][j] == 1 or img_adjacency[j][i] == 1: 174 | return True 175 | else: 176 | return False 177 | 178 | def has_resected_pair(unresected_idx, resected_imgs, img_adjacency): 179 | """Return true if unresected_idx image has matches to >= 1 currently resected image(s) """ 180 | for idx in resected_imgs: 181 | if img_adjacency[unresected_idx][idx] == 1 or img_adjacency[idx][unresected_idx] == 1: 182 | return True 183 | return False 184 | 185 | def has_unresected_pair(resected_idx, unresected_imgs, img_adjacency): 186 | """Return true if resected_idx image has matches to >= 1 currently unresected image(s) """ 187 | for idx in unresected_imgs: 188 | if img_adjacency[resected_idx][idx] == 1 or img_adjacency[idx][resected_idx] == 1: 189 | return True 190 | return False 191 | 192 | 193 | def next_img_pair_to_grow_reconstruction(n_imgs, init_pair, resected_imgs, unresected_imgs, img_adjacency): 194 | """ 195 | Given initial image pair, resect images between the initial ones, then extend reconstruction in both directions. 196 | 197 | :param n_imgs: Number of images to be used in reconstruction 198 | :param init_pair: tuple of indicies of images used to initialize reconstruction 199 | :param resected_imgs: List of indices of resected images 200 | :param unresected_imgs: List of indices of unresected images 201 | :param img_adjacency: Matrix with value at indices i and j = 1 if images have matches, else 0 202 | """ 203 | 204 | if len(unresected_imgs) == 0: raise ValueError('Should not check next image to resect if all have been resected already!') 205 | straddle = False 206 | if init_pair[1] - init_pair[0] > n_imgs/2 : straddle = True #initial pair straddles "end" of the circle (ie if init pair is idxs (0, 49) for 50 images) 207 | 208 | init_arc = init_pair[1] - init_pair[0] + 1 # Number of images between and including initial pair 209 | 210 | #fill in images between initial pair 211 | if len(resected_imgs) < init_arc: 212 | if straddle == False: idx = resected_imgs[-2] + 1 213 | else: idx = resected_imgs[-1] + 1 214 | while True: 215 | if idx not in resected_imgs: 216 | prepend = True 217 | unresected_idx = idx 218 | resected_idx = random.choice(resected_imgs) 219 | return resected_idx, unresected_idx, prepend 220 | idx = idx + 1 % n_imgs 221 | 222 | extensions = len(resected_imgs) - init_arc # How many images have been resected after the initial arc 223 | if straddle == True: #smaller init_idx should be increased and larger decreased 224 | if extensions % 2 == 0: 225 | unresected_idx = (init_pair[0] + int(extensions/2) + 1) % n_imgs 226 | resected_idx = (unresected_idx - 1) % n_imgs 227 | else: 228 | unresected_idx = (init_pair[1] - int(extensions/2) - 1) % n_imgs 229 | resected_idx = (unresected_idx + 1) % n_imgs 230 | else: 231 | if extensions % 2 == 0: 232 | unresected_idx = (init_pair[1] + int(extensions/2) + 1) % n_imgs 233 | resected_idx = (unresected_idx - 1) % n_imgs 234 | else: 235 | unresected_idx = (init_pair[0] - int(extensions/2) - 1) % n_imgs 236 | resected_idx = (unresected_idx + 1) % n_imgs 237 | 238 | prepend = False 239 | return resected_idx, unresected_idx, prepend 240 | 241 | def check_and_get_unresected_point(resected_kpt_idx, match, resected_idx, unresected_idx): 242 | """ 243 | Check if a 3D point seen by the given resected image is involved in a match to the unresected image 244 | and is therefore usable for Pnp. 245 | 246 | :param resected_kpt_idx: Index of keypoint in keypoints list for resected image 247 | :param match: cv2.Dmatch object 248 | :resected_idx: Index of the resected image 249 | :unresected_idx: Index of the unresected image 250 | """ 251 | if resected_idx < unresected_idx: 252 | if resected_kpt_idx == match.queryIdx: 253 | unresected_kpt_idx = match.trainIdx 254 | success = True 255 | return unresected_kpt_idx, success 256 | else: 257 | return None, False 258 | elif unresected_idx < resected_idx: 259 | if resected_kpt_idx == match.trainIdx: 260 | unresected_kpt_idx = match.queryIdx 261 | success = True 262 | return unresected_kpt_idx, success 263 | else: 264 | return None, False 265 | 266 | def get_correspondences_for_pnp(resected_idx, unresected_idx, pts3d, matches, keypoints): 267 | """ 268 | Returns index aligned lists of 3D and 2D points to be used for Pnp. For each 3D point check if it is seen 269 | by the resected image, if so check if there is a match for it between the resected and unresected image. 270 | If so that point will be used in Pnp. Also keeps track of matches that do not have associated 3D points, 271 | and therefore need to be triangulated. 272 | 273 | :param resected_idx: Index of resected image to be used in Pnp 274 | :param unresected_idx Index of unresected image to be used in Pnp 275 | :param pts3d: List of Point3D_with_views objects 276 | :param matches: List of lists of lists where matches[i][j][k] is the kth cv2.Dmatch object for images i and j 277 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 278 | """ 279 | idx1, idx2 = get_idxs_in_correct_order(resected_idx, unresected_idx) 280 | triangulation_status = np.ones(len(matches[idx1][idx2])) # if triangulation_status[x] = 1, then matches[x] used for triangulation 281 | pts3d_for_pnp = [] 282 | pts2d_for_pnp = [] 283 | for pt3d in pts3d: 284 | if resected_idx not in pt3d.source_2dpt_idxs: continue 285 | resected_kpt_idx = pt3d.source_2dpt_idxs[resected_idx] 286 | for k in range(len(matches[idx1][idx2])): 287 | unresected_kpt_idx, success = check_and_get_unresected_point(resected_kpt_idx, matches[idx1][idx2][k], resected_idx, unresected_idx) 288 | if not success: continue 289 | pt3d.source_2dpt_idxs[unresected_idx] = unresected_kpt_idx #Add new 2d/3d correspondences to 3D point object 290 | pts3d_for_pnp.append(pt3d.point3d) 291 | pts2d_for_pnp.append(keypoints[unresected_idx][unresected_kpt_idx].pt) 292 | triangulation_status[k] = 0 293 | 294 | return pts3d, pts3d_for_pnp, pts2d_for_pnp, triangulation_status 295 | 296 | def do_pnp(pts3d_for_pnp, pts2d_for_pnp, K, iterations=200, reprojThresh=5): 297 | """ 298 | Performs Pnp with Ransac implemented manually. The camera pose which has the most inliers (points which 299 | when reprojected are sufficiently close to their keypoint coordinate) is deemed best and is returned. 300 | 301 | :param pts3d_for_pnp: list of index aligned 3D coordinates 302 | :param pts2d_for_pnp: list of index aligned 2D coordinates 303 | :param K: Intrinsics matrix 304 | :param iterations: Number of Ransac iterations 305 | :param reprojThresh: Max reprojection error for point to be considered an inlier 306 | """ 307 | list_pts3d_for_pnp = pts3d_for_pnp 308 | list_pts2d_for_pnp = pts2d_for_pnp 309 | pts3d_for_pnp = np.squeeze(np.array(pts3d_for_pnp)) 310 | pts2d_for_pnp = np.expand_dims(np.squeeze(np.array(pts2d_for_pnp)), axis=1) 311 | num_pts = len(pts3d_for_pnp) 312 | 313 | highest_inliers = 0 314 | for i in range(iterations): 315 | pt_idxs = np.random.choice(num_pts, 6, replace=False) 316 | pts3 = np.array([pts3d_for_pnp[pt_idxs[i]] for i in range(len(pt_idxs))]) 317 | pts2 = np.array([pts2d_for_pnp[pt_idxs[i]] for i in range(len(pt_idxs))]) 318 | _, rvec, tvec = cv2.solvePnP(pts3, pts2, K, distCoeffs=np.array([]), flags=cv2.SOLVEPNP_ITERATIVE) 319 | R, _ = cv2.Rodrigues(rvec) 320 | pnp_errors, projpts, avg_err, perc_inliers = test_reproj_pnp_points(list_pts3d_for_pnp, list_pts2d_for_pnp, R, tvec, K, rep_thresh=reprojThresh) 321 | if highest_inliers < perc_inliers: 322 | highest_inliers = perc_inliers 323 | best_R = R 324 | best_tvec = tvec 325 | R = best_R 326 | tvec = best_tvec 327 | print('rvec:', rvec,'\n\ntvec:', tvec) 328 | 329 | return R, tvec 330 | 331 | def prep_for_reproj(img_idx, points3d_with_views, keypoints): 332 | """ 333 | Returns aligned vectors of 2D and 3D points to be used for reprojection 334 | 335 | :param img_idx: Index of image for which reprojection errors are desired 336 | :param points3d_with_views: List of Point3D_with_views objects. Will have new points appended to it 337 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 338 | """ 339 | points_3d = [] 340 | points_2d = [] 341 | pt3d_idxs = [] 342 | i = 0 343 | for pt3d in points3d_with_views: 344 | if img_idx in pt3d.source_2dpt_idxs.keys(): 345 | pt3d_idxs.append(i) 346 | points_3d.append(pt3d.point3d) 347 | kpt_idx = pt3d.source_2dpt_idxs[img_idx] 348 | points_2d.append(keypoints[img_idx][kpt_idx].pt) 349 | i += 1 350 | 351 | return np.array(points_3d), np.array(points_2d), pt3d_idxs 352 | 353 | def calculate_reproj_errors(projPoints, points_2d): 354 | """ 355 | Calculate reprojection errors (L1) between projected points and ground truth (keypoint coordinates) 356 | 357 | :param projPoints: list of index aligned projected points 358 | :param points_2d: list of index aligned corresponding keypoint coordinates 359 | """ 360 | assert len(projPoints) == len(points_2d) 361 | delta = [] 362 | for i in range(len(projPoints)): 363 | delta.append(abs(projPoints[i] - points_2d[i])) 364 | 365 | average_delta = sum(delta)/len(delta) # 2-vector, average error for x and y coord 366 | average_delta = (average_delta[0] + average_delta[1])/2 # average error overall 367 | 368 | return average_delta, delta 369 | 370 | def get_reproj_errors(img_idx, points3d_with_views, R, t, K, keypoints, distCoeffs=np.array([])): 371 | """ 372 | Project all 3D points seen in image[img_idx] onto it, return reprojection errors and average error 373 | 374 | :param img_idx: Index of image for which reprojection errors are desired 375 | :param points3d_with_views: List of Point3D_with_views objects. Will have new points appended to it 376 | :param R: Rotation matrix 377 | :param t: Translation vector 378 | :param K: Intrinsics matrix 379 | :param keypoints: List of lists of cv2.Keypoint objects. keypoints[i] is list for image i. 380 | """ 381 | points_3d, points_2d, pt3d_idxs = prep_for_reproj(img_idx, points3d_with_views, keypoints) 382 | rvec, _ = cv2.Rodrigues(R) 383 | projPoints, _ = cv2.projectPoints(points_3d, rvec, t, K, distCoeffs=distCoeffs) 384 | projPoints = np.squeeze(projPoints) 385 | avg_error, errors = calculate_reproj_errors(projPoints, points_2d) 386 | 387 | return points_3d, points_2d, avg_error, errors 388 | 389 | def test_reproj_pnp_points(pts3d_for_pnp, pts2d_for_pnp, R_new, t_new, K, rep_thresh=5): 390 | """ 391 | Reprojects points fed into Pnp back onto camera whose R and t were just obtained via Pnp. 392 | Used to assess how good the resection was. 393 | 394 | :param pts3d_for_pnp: List of axis aligned 3D points 395 | :param pts2d_for_pnp: List of axis aligned 2D points 396 | :param R_new: Rotation matrix of newly resected image 397 | :param t_new: Translation vector of newly resected image 398 | :param rep_thresh: Number of pixels reprojected points must be within to qualify as inliers 399 | """ 400 | errors = [] 401 | projpts = [] 402 | inliers = [] 403 | for i in range(len(pts3d_for_pnp)): 404 | Xw = pts3d_for_pnp[i][0] 405 | Xr = np.dot(R_new, Xw).reshape(3,1) 406 | Xc = Xr + t_new 407 | x = np.dot(K, Xc) 408 | x /= x[2] 409 | errors.append([np.float64(x[0] - pts2d_for_pnp[i][0]), np.float64(x[1] - pts2d_for_pnp[i][1])]) 410 | projpts.append(x) 411 | if abs(errors[-1][0]) > rep_thresh or abs(errors[-1][1]) > rep_thresh: inliers.append(0) 412 | else: inliers.append(1) 413 | a = 0 414 | for e in errors: 415 | a = a + abs(e[0]) + abs(e[1]) 416 | avg_err = a/(2*len(errors)) 417 | perc_inliers = sum(inliers)/len(inliers) 418 | 419 | return errors, projpts, avg_err, perc_inliers 420 | -------------------------------------------------------------------------------- /results/results_collage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rshilliday/sfm/ca0eead387ba68582bf166c9a0780adcd99e3bf3/results/results_collage.png --------------------------------------------------------------------------------