├── .gitignore ├── .style.yapf ├── FAQ.md ├── LICENSE ├── README.md ├── python_toolbox ├── convert_to_logfile.py ├── download_t2_dataset.py ├── evaluation │ ├── README.md │ ├── config.py │ ├── evaluation.py │ ├── images │ │ ├── f-score.jpg │ │ ├── precision.jpg │ │ └── recall.jpg │ ├── plot.py │ ├── registration.py │ ├── requirements.txt │ ├── run.py │ ├── trajectory_io.py │ └── util.py ├── get_colmap_reconstruction.sh ├── interpolate_log_file.py └── upload_t2_results.py └── test_data ├── Ignatius_mapping.txt ├── mapping.txt └── test.log /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /.style.yapf: -------------------------------------------------------------------------------- 1 | [style] 2 | based_on_style = google 3 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ### Should I start with video or image set? 4 | The image sets are sampled frames from the video. We provide it because many off-the-shelf reconstruction systems cannot directly take videos as input. For beginners, start with image sets. You can also refer to [this tutorial page](https://tanksandtemples.org/tutorial/) for instructions on how to setup a workable system. For advanced users, please work with the videos since they are the raw 4K videos we captured with a high end camera. 5 | 6 | ### I cannot run the python scripts 7 | The python scripts run on Python 2.7 or 3.x. Older versions of python are not supported. For python 2.7, the ``requests`` package is needed. You can install it with the following command: 8 | ``` 9 | sudo pip install requests 10 | ``` 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | TanksAndTemples Website Toolbox 2 | http://www.tanksandtemples.org 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2017 7 | Arno Knapitsch 8 | Jaesik Park 9 | Qian-Yi Zhou 10 | Vladlen Koltun 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DISCONTINUATION OF PROJECT # 2 | This project will no longer be maintained by Intel. 3 | Intel has ceased development and contributions including, but not limited to, maintenance, bug fixes, new releases, or updates, to this project. 4 | Intel no longer accepts patches to this project. 5 | If you have an ongoing need to use this project, are interested in independently developing it, or would like to maintain patches for the open source software community, please create your own fork of this project. 6 | 7 | # Tanks and Temples 8 | 9 | This repository is used for discussing issues regarding the website that hosts the *Tanks and Temples* dataset. 10 | http://www.tanksandtemples.org 11 | 12 | In order to evaluate your reconstruction algorithm on our benchmark, you need to download the dataset, reconstruct 3d geometry, submit your results, get evaluated, and be put on the leaderboard. Please follow the instructions on the website. If you encounter any problem, first check if the problem is listed on [FAQ](FAQ.md). If not, go to the [issues page](https://github.com/IntelVCL/TanksAndTemples/issues) to search if there is any duplicate of your problem. If not, file an issue and we will respond as fast as we can. Alternatively, you can send an email to [info.tanksandtemples@ivcl.org](mailto:info.tanksandtemples@ivcl.org). 13 | 14 | ## Python scripts 15 | 16 | The [python_toolbox](python_toolbox) folder includes the python scripts for downloading the dataset and uploading reconstruction results. The python scripts are under the [MIT license](LICENSE). The dataset itself has a different license, see [this page](https://tanksandtemples.org/license/) for details. 17 | 18 | Usage of downloader: 19 | ``` 20 | > python download_t2_dataset.py [-h] [-s] [--modality MODALITY] [--group GROUP] [--unpack_off] [--calc_md5_off] 21 | 22 | Example 1: download all videos for intermediate and advanced scenes 23 | > python download_t2_dataset.py --modality video --group both 24 | 25 | Example 2: download image sets for intermediate scenes (quick start setting) 26 | > python download_t2_dataset.py --modality image --group intermediate 27 | 28 | Example 3: show the status of downloaded data 29 | > python download_t2_dataset.py -s 30 | ``` 31 | 32 | Usage of uploader: 33 | ``` 34 | > python upload_t2_results.py [-h] [--group GROUP] 35 | 36 | Example 1: upload intermediate and advanced reconstruction results 37 | > python upload_t2_results.py --group both 38 | 39 | Example 2: upload only intermediate results 40 | > python upload_t2_results.py --group intermediate 41 | ``` 42 | -------------------------------------------------------------------------------- /python_toolbox/convert_to_logfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # ---------------------------------------------------------------------------- 4 | # - TanksAndTemples Website Toolbox - 5 | # - http://www.tanksandtemples.org - 6 | # ---------------------------------------------------------------------------- 7 | # The MIT License (MIT) 8 | # 9 | # Copyright (c) 2017 10 | # Arno Knapitsch 11 | # Jaesik Park 12 | # Qian-Yi Zhou 13 | # Vladlen Koltun 14 | # 15 | # Permission is hereby granted, free of charge, to any person obtaining a copy 16 | # of this software and associated documentation files (the "Software"), to deal 17 | # in the Software without restriction, including without limitation the rights 18 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | # copies of the Software, and to permit persons to whom the Software is 20 | # furnished to do so, subject to the following conditions: 21 | # 22 | # The above copyright notice and this permission notice shall be included in 23 | # all copies or substantial portions of the Software. 24 | # 25 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | # THE SOFTWARE. 32 | # ---------------------------------------------------------------------------- 33 | # 34 | # Python script to convert SfM data into the tanksandtempls log file format 35 | # Example: 36 | # python convert_to_logfile.py [COLMAP SfM file] \ 37 | # [output log-filename] \ 38 | # [folder of the input images] \ 39 | # [COLMAP/MVE/VSFM] \ 40 | # [image format] \ 41 | # check https://www.tanksandtemples.org/tutorial/ for further examples 42 | 43 | import sys 44 | import os 45 | import glob 46 | import numpy as np 47 | from numpy import matrix 48 | import read_model 49 | 50 | 51 | def write_SfM_log(T, i_map, filename): 52 | with open(filename, 'w') as f: 53 | ii = 0 54 | for t in T: 55 | p = t.tolist() 56 | f.write(' '.join(map(str, i_map[ii])) + '\n') 57 | f.write('\n'.join(' '.join(map('{0:.12f}'.format, p[i])) \ 58 | for i in range(4))) 59 | f.write('\n') 60 | ii = ii + 1 61 | 62 | 63 | def quat2rotmat(qvec): 64 | rotmat = np.array([1- 2 * qvec[2]**2 - 2 * qvec[3]**2, \ 65 | 2 * qvec[1] * qvec[2] - 2 * qvec[0] * qvec[3], \ 66 | 2 * qvec[3] * qvec[1] + 2 * qvec[0] * qvec[2], \ 67 | \ 68 | 2 * qvec[1] * qvec[2] + 2 * qvec[0] * qvec[3], \ 69 | 1 - 2 * qvec[1]**2 - 2 * qvec[3]**2, \ 70 | 2 * qvec[2] * qvec[3] - 2 * qvec[0] * qvec[1], \ 71 | \ 72 | 2 * qvec[3] * qvec[1] - 2 * qvec[0] * qvec[2], \ 73 | 2 * qvec[2] * qvec[3] + 2 * qvec[0] * qvec[1], \ 74 | 1 - 2 * qvec[1]**2 - 2 * qvec[2]**2]) 75 | rotmat = rotmat.reshape(3, 3) 76 | return rotmat 77 | 78 | 79 | # Usage: convert_COLMAP_to_log([COLMAP SfM file], [output log-filename], \ 80 | # [folder of the input images] [image format]) 81 | # Example: convert_COLMAP_to_log('sparse/0/', 'colmap.log', 'images/','jpg') 82 | def convert_COLMAP_to_log(filename, logfile_out, input_images, formatp): 83 | dirname = os.path.dirname(filename) 84 | cameras, images, points3D = read_model.read_model(dirname, '.bin') 85 | jpg_list = glob.glob(input_images + '/*.' + formatp) 86 | jpg_list.sort() 87 | nr_of_images = len(jpg_list) 88 | 89 | T = [] 90 | i_map = [] 91 | TF = [] 92 | i_mapF = [] 93 | 94 | ii = 0 95 | for key, im in images.items(): 96 | qvec = im[1] 97 | r = quat2rotmat(qvec) 98 | translation = im[2] 99 | w = np.zeros((4, 4)) 100 | w[3, 3] = 1 101 | w[0:3, 0:3] = r 102 | w[0:3, 3] = translation 103 | A = matrix(w) 104 | T.append(A.I) 105 | image_name = im[4] 106 | matching = [i for i, s in enumerate(jpg_list) if image_name in s] 107 | ii = im[0] 108 | i_map.append([ii, matching[0], 0]) 109 | idm = np.identity(4) 110 | # log file needs an entry for every input image, if image is not part of 111 | # the SfM bundle it will be assigned to the identity matrix 112 | for k in range(0, nr_of_images): 113 | try: 114 | # find the id of view nr. k 115 | view_id = [i for i, item in enumerate(i_map) if k == item[1]][0] 116 | i_mapF.append(np.array([k, k, 0.0], dtype='int')) 117 | TF.append(T[view_id]) 118 | except: 119 | i_mapF.append(np.array([k, -1, 0.0], dtype='int')) 120 | TF.append(idm) 121 | write_SfM_log(TF, i_mapF, logfile_out) 122 | 123 | 124 | # USAGE: convert_MVE_to_log([MVE SfM file] [output log-filename] \ 125 | # [folder containing the mve views]) 126 | # EXAMPLE: convert_MVE_to_log('synth_0.out','mve.log','views/') 127 | def convert_MVE_to_log(filename, logfile_out, views_folder): 128 | bundlefile = filename 129 | lines = open(bundlefile).read().split('\n') 130 | views_list = glob.glob(views_folder + '/*/') 131 | views_list.sort() 132 | nr_of_views = len(views_list) 133 | nr_of_images = int(lines[1].split(' ')[0]) 134 | 135 | T = [] 136 | i_map = [] 137 | TF = [] 138 | i_mapF = [] 139 | 140 | image_list = [] 141 | ii = 0 142 | for x in range(0, nr_of_views): 143 | meta_filename = views_list[x] + 'meta.ini' 144 | lines_m = open(meta_filename).read().split('\n') 145 | matching_i = [i for i, s in enumerate(lines_m) if 'name = ' in s] 146 | orig_img = lines_m[matching_i[0]].split('= ')[1] 147 | image_list.append(orig_img) 148 | image_list.sort() 149 | 150 | for x in range(0, nr_of_views): 151 | meta_filename = views_list[x] + 'meta.ini' 152 | lines_m = open(meta_filename).read().split('\n') 153 | matching_r = [i for i, s in enumerate(lines_m) if 'rotation' in s] 154 | if (len(matching_r)): 155 | r_line = lines_m[matching_r[0]].split('= ')[1] 156 | r = np.array(r_line.split(' '), dtype='double').reshape(3, 3) 157 | matching_t = [ 158 | i for i, s in enumerate(lines_m) if 'translation' in s 159 | ] 160 | t_line = lines_m[matching_t[0]].split('= ')[1] 161 | translation = np.array(t_line.split(' ')[0:3], dtype='double') 162 | w = np.zeros((4, 4)) 163 | w[3, 3] = 1 164 | w[0:3, 0:3] = r 165 | w[0:3, 3] = translation 166 | A = matrix(w) 167 | T.append(A.I) 168 | matching_i = [i for i, s in enumerate(lines_m) if 'name = ' in s] 169 | orig_img = lines_m[matching_i[0]].split('= ')[1] 170 | matching_io = [i for i, s in enumerate(image_list) if orig_img in s] 171 | i_map.append([x, matching_io[0], 0]) 172 | idm = np.identity(4) 173 | # log file needs an entry for every input image, if image is not part of 174 | # the SfM bundle it will be assigned to the identity matrix 175 | for k in range(0, nr_of_images): 176 | try: 177 | # find the bundler id of view nr. k 178 | view_id = [i for i, item in enumerate(i_map) if k == item[1]][0] 179 | i_mapF.append(np.array([k, k, 0.0], dtype='int')) 180 | TF.append(T[view_id]) 181 | except: 182 | i_mapF.append(np.array([k, -1, 0.0], dtype='int')) 183 | TF.append(idm) 184 | write_SfM_log(TF, i_mapF, logfile_out) 185 | 186 | 187 | # Usage: convert_VSFM_to_log([VSfM *.nvm SfM file] [output log-filename] \ 188 | # [folder of the input images] [image format]) 189 | # Example: convert_VSFM_to_log('result.nvm', 'vsfm.log', 'images/', 'jpg') 190 | def convert_VSFM_to_log(filename, logfile_out, input_images, formatp): 191 | bundlefile = filename 192 | lines = open(bundlefile).read().split('\n') 193 | nr_of_views = int(lines[2]) 194 | jpg_list = glob.glob(input_images + '/*.' + formatp) 195 | jpg_list.sort() 196 | nr_of_images = len(jpg_list) 197 | 198 | T = [] 199 | i_map = [] 200 | TF = [] 201 | i_mapF = [] 202 | ii = 0 203 | 204 | for x in range(3, nr_of_views + 3): 205 | line_split = lines[x].split(' ') 206 | qvec = np.array([float(line_split[1]), float(line_split[2]), \ 207 | float(line_split[3]), float(line_split[4])]) 208 | r = quat2rotmat(qvec) 209 | t1x = np.array([float(line_split[5]), float(line_split[6]), \ 210 | float(line_split[7])]) 211 | r = r * np.array([[1], [-1], [-1]]) # no idea why this is necessary 212 | translation = np.dot(-r, t1x) 213 | w = np.zeros((4, 4)) 214 | w[3, 3] = 1 215 | w[0:3, 0:3] = r 216 | w[0:3, 3] = translation 217 | A = matrix(w) 218 | T.append(A.I) 219 | image_name = line_split[0].split('\t')[0] 220 | matching = [i for i, s in enumerate(jpg_list) if image_name in s] 221 | ii = x - 3 222 | i_map.append([ii, matching[0], 0]) 223 | idm = np.identity(4) 224 | 225 | # log file needs an entry for every input image, if image is not part of 226 | # the SfM bundle it will be assigned to the identity matrix 227 | for k in range(0, nr_of_images): 228 | try: 229 | # find the bundler id of view nr. k 230 | view_id = [i for i, item in enumerate(i_map) if k == item[1]][0] 231 | i_mapF.append(np.array([k, view_id, 0.0], dtype='int')) 232 | TF.append(T[view_id]) 233 | except: 234 | i_mapF.append(np.array([k, -1, 0.0], dtype='int')) 235 | TF.append(idm) 236 | write_SfM_log(TF, i_mapF, logfile_out) 237 | 238 | 239 | if __name__ == '__main__': 240 | 241 | filename = sys.argv[1] 242 | logfile_out = sys.argv[2] 243 | input_images = sys.argv[3] 244 | method = sys.argv[4] 245 | formatp = sys.argv[5] 246 | 247 | if method == 'COLMAP': 248 | convert_COLMAP_to_log(filename, logfile_out, input_images, formatp) 249 | if method == 'MVE': 250 | convert_MVE_to_log(filename, logfile_out, input_images) 251 | if method == 'VSFM': 252 | convert_VSFM_to_log(filename, logfile_out, input_images, formatp) 253 | -------------------------------------------------------------------------------- /python_toolbox/download_t2_dataset.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for downloading dataset from www.tanksandtemples.org 33 | # The dataset has a different license, please refer to 34 | # https://tanksandtemples.org/license/ 35 | 36 | import sys 37 | import os 38 | import argparse 39 | import zipfile 40 | import hashlib 41 | import requests 42 | if (sys.version_info > (3, 0)): 43 | pversion = 3 44 | from urllib.request import Request, urlopen 45 | else: 46 | pversion = 2 47 | from urllib2 import Request, urlopen 48 | 49 | id_download_dict = { 50 | 'Auditorium.mp4': '0B-ePgl6HF260SmdGUzJSX0ZfZXc', 51 | 'Auditorium.zip': '0B-ePgl6HF260N1VHWFBTSWQ2MDg', 52 | 'Ballroom.mp4': '0B-ePgl6HF260MzlmY2Jwa0dqME0', 53 | 'Ballroom.zip': '0B-ePgl6HF260aS1hQXJHeHFxNVE', 54 | 'Barn.mp4': '0B-ePgl6HF260ZlBZcHFrTHFLdGM', 55 | 'Barn.zip': '0B-ePgl6HF260NzQySklGdXZyQzA', 56 | 'Church.mp4': '0B-ePgl6HF260dnlGMkFkNlpibG8', 57 | 'Church.zip': '0B-ePgl6HF260SmhXM0czaHJ3SU0', 58 | 'Caterpillar.mp4': '0B-ePgl6HF260Z00xVWgyN2c3WEU', 59 | 'Caterpillar.zip': '0B-ePgl6HF260b2JNbnZYYjczU2s', 60 | 'Courthouse.mp4': '0B-ePgl6HF260TEpnajBqRFJ1enM', 61 | 'Courthouse.zip': '0B-ePgl6HF260bHRNZTJnU1pWMVE', 62 | 'Courtroom.mp4': '0B-ePgl6HF260b0JZeUJlUThSWjQ', 63 | 'Courtroom.zip': '0B-ePgl6HF260UmZIQVgtLXhtZUE', 64 | 'Family.mp4': '0B-ePgl6HF260UmNxYmlQeDhmeFE', 65 | 'Family.tar.gz': '0B-ePgl6HF260SWRlRDZCRXZRZlk', 66 | 'Family.zip': '0B-ePgl6HF260NVRhRmxnTW4tQTQ', 67 | 'Francis.mp4': '0B-ePgl6HF260emtkUElRT0lXQ3M', 68 | 'Francis.tar.gz': '0B-ePgl6HF260MnVqcW1EWDVMcFE', 69 | 'Francis.zip': '0B-ePgl6HF260SHk4ejdaSEhqd28', 70 | 'Horse.mp4': '0B-ePgl6HF260RGFBcF9iTk5XQTA', 71 | 'Horse.tar.gz': '0B-ePgl6HF260eE9EVTdpS3hYamc', 72 | 'Horse.zip': '0B-ePgl6HF260VFdBc0RvQjJuQXc', 73 | 'Ignatius.mp4': '0B-ePgl6HF260T19oUTIyUTRwTE0', 74 | 'Ignatius.zip': '0B-ePgl6HF260d0l0ZDNSZ3ZxREk', 75 | 'Lighthouse.mp4': '0B-ePgl6HF260T184cUdCbFFBVEE', 76 | 'Lighthouse.zip': '0B-ePgl6HF260dHpldktMNV9NRTA', 77 | 'M60.mp4': '0B-ePgl6HF260dG9nTzZHdkRJblE', 78 | 'M60.zip': '0B-ePgl6HF260b2lSTWxwLU1CQ2s', 79 | 'Meetingroom.mp4': '0B-ePgl6HF260V3BFSFFTZFJwSWc', 80 | 'Meetingroom.zip': '0B-ePgl6HF260cV9lNmlZZGp6aUU', 81 | 'Museum.mp4': '0B-ePgl6HF260ZXRwck5rWk4tc2c', 82 | 'Museum.zip': '0B-ePgl6HF260RTY4Ml9Ubm9fUkk', 83 | 'Palace.mp4': '0B-ePgl6HF260X21ac1ZXNmx3VTA', 84 | 'Palace.zip': '0B-ePgl6HF260ZHlJejlXbmFKS3M', 85 | 'Panther.mp4': '0B-ePgl6HF260bVRndWVYRGM4c0U', 86 | 'Panther.zip': '0B-ePgl6HF260SUNBeVhMc1hpb28', 87 | 'Playground.mp4': '0B-ePgl6HF260d0JoR2pWak9RbnM', 88 | 'Playground.zip': '0B-ePgl6HF260TVktaTFyclFhaDg', 89 | 'Temple.mp4': '0B-ePgl6HF260N1VTMGNES0FsaDA', 90 | 'Temple.zip': '0B-ePgl6HF260V2VaSG5GTkl5dmc', 91 | 'Train.mp4': '0B-ePgl6HF260YUttRUI4U0xtS1E', 92 | 'Train.zip': '0B-ePgl6HF260UFNWeXk3MHhCT00', 93 | 'Truck.mp4': '0B-ePgl6HF260aVVZMzhSdVc5Njg', 94 | 'Truck.zip': '0B-ePgl6HF260NEw3OGN4ckF0dnM', 95 | 'advanced_video.chk': '0B-ePgl6HF260RWJIcjRPRnlUS28', 96 | 'advanced_video.zip': '0B-ePgl6HF260OXgzbEJleDVSZ0k', 97 | 'image_sets_md5.chk': '0B-ePgl6HF260dE5zR3FhQmxVbHc', 98 | 'intermediate_video.chk': '0B-ePgl6HF260SVdpbG1peXBOYnM', 99 | 'intermediate_video.zip': '0B-ePgl6HF260UU1zUTd6SzlmczA', 100 | 'advanced_image.zip': '0B-ePgl6HF260UXlhWDBiNVZvdk0', 101 | 'intermediate_image.zip': '0B-ePgl6HF260UU1zUTd6SzlmczA', 102 | 'advanced_image.chk': '0B-ePgl6HF260RWJIcjRPRnlUS28', 103 | 'intermediate_image.chk': '0B-ePgl6HF260SVdpbG1peXBOYnM', 104 | 'md5.txt': '0B-ePgl6HF260QTlJUXpqc3RQOGM', 105 | 'training.zip': '0B-ePgl6HF260dU1pejdkeXdMb00', 106 | 'video_set_md5.chk': '0B-ePgl6HF260M2h5Q3o1bGdpc1U' 107 | } 108 | 109 | sep = os.sep 110 | parser = argparse.ArgumentParser(description='Tanks and Temples file' + 111 | 'downloader') 112 | parser.add_argument( 113 | '--modality', 114 | type=str, 115 | help='(image|video|both) ' + 116 | 'choose if you want to download video sequences (very big) or pre sampled' + 117 | ' image sets', 118 | default='image') 119 | parser.add_argument( 120 | '--group', 121 | type=str, 122 | help='(intermediate|advanced|both|training|all)' + 123 | ' choose if you want to download intermediate, advanced or training dataset', 124 | default='both') 125 | parser.add_argument('--pathname', 126 | type=str, 127 | help='chose destination path name, default = local path', 128 | default='') 129 | parser.add_argument('-s', 130 | action='store_true', 131 | default=False, 132 | dest='status', 133 | help='show data status') 134 | parser.add_argument('--unpack_off', 135 | action='store_false', 136 | default=True, 137 | dest='unpack', 138 | help='do not un-zip the folders after download') 139 | parser.add_argument('--calc_md5_off', 140 | action='store_false', 141 | default=True, 142 | dest='calc_md5', 143 | help='do not calculate md5sum after download') 144 | 145 | 146 | def download_file_from_google_drive(id, destination): 147 | URL = "https://docs.google.com/uc?export=download" 148 | session = requests.Session() 149 | response = session.get(URL, params={'id': id}, stream=True) 150 | token = get_confirm_token2(response) 151 | if token: 152 | params = {'id': id, 'confirm': token} 153 | response = session.get(URL, params=params, stream=True) 154 | save_response_content(response, destination) 155 | 156 | 157 | def get_confirm_token(response): 158 | for key, value in response.cookies.items(): 159 | if key.startswith('download_warning'): 160 | return value 161 | return None 162 | 163 | 164 | def get_confirm_token2(response): 165 | for key, value in response.headers.items(): 166 | if key.startswith('Set-Cookie'): 167 | return value.split('=')[1].split(';')[0] 168 | return None 169 | 170 | 171 | def save_response_content(response, destination): 172 | CHUNK_SIZE = 32768 173 | 174 | if not os.path.exists(os.path.dirname(destination)): 175 | os.makedirs(os.path.dirname(destination)) 176 | total_filesize = 0 177 | with open(destination, "wb") as f: 178 | for chunk in response.iter_content(CHUNK_SIZE): 179 | if chunk: # filter out keep-alive new chunks 180 | f.write(chunk) 181 | total_filesize += CHUNK_SIZE 182 | sys.stdout.write("\r%5.0f MB downloaded" % 183 | (float(total_filesize) / 1000000)) 184 | sys.stdout.flush() 185 | sys.stdout.write("\rDownload Complete \n") 186 | sys.stdout.flush() 187 | return chunk 188 | 189 | 190 | def generate_file_md5(filename, blocksize=2**20): 191 | m = hashlib.md5() 192 | with open(filename, "rb") as f: 193 | while True: 194 | buf = f.read(blocksize) 195 | if not buf: 196 | break 197 | m.update(buf) 198 | return m.hexdigest() 199 | 200 | 201 | def download_video(pathname, scene, image_md5_dict, calc_md5): 202 | scene_out_dir = pathname + 'videos' 203 | download_file = scene + '.mp4' 204 | print('\ndownloading video ' + download_file.split('/')[-1]) 205 | idd = id_download_dict[download_file] 206 | download_file_local = scene_out_dir + sep + scene + '.mp4' 207 | download_file_from_google_drive(idd, download_file_local) 208 | 209 | if (calc_md5): 210 | h_md5 = generate_file_md5(download_file_local) 211 | print('\nmd5 downloaded: ' + h_md5) 212 | print('md5 original: ' + video_md5_dict[scene]) 213 | md5_check = h_md5 == video_md5_dict[scene] 214 | 215 | if (not md5_check): 216 | print('\nWarning: MD5 does not match, delete file and restart' + 217 | ' download\n') 218 | else: 219 | if (unpack): 220 | extr_dir = scene_out_dir 221 | zip_file = scene_out_dir + sep + scene + '.zip' 222 | if (zipfile.is_zipfile(zip_file)): 223 | if not os.path.exists(extr_dir): 224 | os.makedirs(extr_dir) 225 | zip = zipfile.ZipFile(zip_file, 'r') 226 | zip.extractall(extr_dir) 227 | 228 | 229 | def check_video(pathname, scene, image_md5_dict): 230 | scene_out_dir = pathname + 'videos' 231 | ret_str = ' ' 232 | download_file_local = scene_out_dir + sep + scene + '.mp4' 233 | if os.path.exists(download_file_local): 234 | h_md5 = generate_file_md5(download_file_local) 235 | md5_check = h_md5 == video_md5_dict[scene] 236 | if (md5_check): 237 | ret_str = 'X' 238 | else: 239 | ret_str = '?' 240 | else: 241 | ret_str = ' ' 242 | return ret_str 243 | 244 | 245 | def download_image_sets(pathname, scene, image_md5_dict, calc_md5): 246 | scene_out_dir = pathname + 'image_sets' 247 | download_file = scene + '.zip' 248 | download_file_local = scene_out_dir + sep + scene + '.zip' 249 | print('\ndownloading image set ' + download_file.split('/')[-1]) 250 | idd = id_download_dict[download_file] 251 | download_file_from_google_drive(idd, download_file_local) 252 | 253 | if (calc_md5): 254 | h_md5 = generate_file_md5(download_file_local) 255 | print('\nmd5 downloaded: ' + h_md5) 256 | print('md5 original: ' + image_md5_dict[scene]) 257 | md5_check = h_md5 == image_md5_dict[scene] 258 | 259 | if (md5_check): 260 | if (unpack): 261 | extr_dir = scene_out_dir 262 | 263 | zip_file = scene_out_dir + sep + scene + '.zip' 264 | if (zipfile.is_zipfile(zip_file)): 265 | if not os.path.exists(extr_dir): 266 | os.makedirs(extr_dir) 267 | zip = zipfile.ZipFile(zip_file, 'r') 268 | zip.extractall(extr_dir) 269 | else: 270 | print('\nWarning: MD5 does not match, delete file and restart' + 271 | ' download\n') 272 | 273 | 274 | def check_image_sets(pathname, scene, image_md5_dict): 275 | scene_out_dir = pathname + 'image_sets' 276 | ret_str = '' 277 | download_file_local = scene_out_dir + sep + scene + '.zip' 278 | if os.path.exists(download_file_local): 279 | h_md5 = generate_file_md5(download_file_local) 280 | md5_check = h_md5 == image_md5_dict[scene] 281 | if (md5_check): 282 | ret_str = 'X' 283 | else: 284 | ret_str = '?' 285 | else: 286 | ret_str = ' ' 287 | return ret_str 288 | 289 | 290 | def print_status(sequences, modality, pathname, intermediate_list, 291 | advanced_list, training_list, image_md5_dict, video_md5_dict): 292 | #print('intermediate Dataset \t\t\t Video \t\t\t image set') 293 | print('\n\n data status: \n\n') 294 | print('[X] - downloaded [ ] - missing [?] - being downloaded or ' + 295 | 'corrupted [n] - not checked') 296 | 297 | if (sequences == 'intermediate' or sequences == 'both' or 298 | sequences == 'all' or sequences == ''): 299 | print('\n\n---------------------------------------------------------' + 300 | '--------') 301 | line_new = '%12s %12s %12s' % (' intermediate Dataset', 'Video', 302 | 'image set') 303 | print(line_new) 304 | print('-----------------------------------------------------------' + 305 | '------') 306 | for scene in intermediate_list: 307 | line_new = '%12s %19s %10s' % ( 308 | scene, check_video(pathname, scene, video_md5_dict) if 309 | (modality == 'video' or modality == 'both' or modality == '') 310 | else 'n', check_image_sets(pathname, scene, image_md5_dict) if 311 | (modality == 'image' or modality == 'both' or 312 | modality == '') else 'n') 313 | print(line_new) 314 | 315 | if (sequences == 'advanced' or sequences == 'both' or sequences == 'all' or 316 | sequences == ''): 317 | print('\n\n------------------------------------------------------' + 318 | '---------') 319 | line_new = '%12s %16s %12s' % (' advanced Dataset', 'Video', 320 | 'image set') 321 | print(line_new) 322 | print('---------------------------------------------------------------') 323 | for scene in advanced_list: 324 | #print(scene + '\t\t\t X \t\t\t X') 325 | line_new = '%12s %19s %10s' % ( 326 | scene, check_video(pathname, scene, video_md5_dict) if 327 | (modality == 'video' or modality == 'both' or modality == '') 328 | else 'n', check_image_sets(pathname, scene, image_md5_dict) if 329 | (modality == 'image' or modality == 'both' or 330 | modality == '') else 'n') 331 | print(line_new) 332 | 333 | if (sequences == 'training' or sequences == 'all' or sequences == ''): 334 | print('\n\n------------------------------------------------------' + 335 | '---------') 336 | line_new = '%12s %16s %12s' % (' training Dataset', 'Video', 337 | 'image set') 338 | print(line_new) 339 | print('---------------------------------------------------------------') 340 | for scene in training_list: 341 | #print(scene + '\t\t\t X \t\t\t X') 342 | line_new = '%12s %19s %10s' % ( 343 | scene, check_video(pathname, scene, video_md5_dict) if 344 | (modality == 'video' or modality == 'both' or modality == '') 345 | else 'n', check_image_sets(pathname, scene, image_md5_dict) if 346 | (modality == 'image' or modality == 'both' or 347 | modality == '') else 'n') 348 | print(line_new) 349 | 350 | 351 | if __name__ == "__main__": 352 | intermediate_list = [ 353 | 'Family', 'Francis', 'Horse', 'Lighthouse', 'M60', 'Panther', 354 | 'Playground', 'Train' 355 | ] 356 | advanced_list = [ 357 | 'Auditorium', 'Ballroom', 'Courtroom', 'Museum', 'Palace', 'Temple' 358 | ] 359 | training_list = [ 360 | 'Barn', 'Caterpillar', 'Church', 'Courthouse', 'Ignatius', 361 | 'Meetingroom', 'Truck' 362 | ] 363 | 364 | args = parser.parse_args() 365 | sequences = args.group 366 | calc_md5 = args.calc_md5 367 | 368 | if sequences == 'intermediate': 369 | scene_list = intermediate_list 370 | elif sequences == 'advanced': 371 | scene_list = advanced_list 372 | elif sequences == 'training': 373 | scene_list = training_list 374 | elif sequences == 'both': 375 | scene_list = intermediate_list + advanced_list 376 | elif sequences == 'all': 377 | scene_list = intermediate_list + advanced_list + training_list 378 | elif sequences == '': 379 | scene_list = intermediate_list + advanced_list 380 | else: 381 | sys.exit('Error! Unknown group parameter, see help [-h]') 382 | scene_list.sort() 383 | 384 | modality = args.modality 385 | unpack = args.unpack 386 | status_print = args.status 387 | pathname = args.pathname 388 | if pathname: 389 | pathname = pathname + sep 390 | # download md5 checksum file and create md5 dict for image sets zip files: 391 | image_md5_dict = {} 392 | scene_out_dir = pathname + 'image_sets' 393 | fname = scene_out_dir + sep + 'image_sets_md5.chk' 394 | idd = id_download_dict['image_sets_md5.chk'] 395 | 396 | print('\ndownloading md5 sum file for image sets') 397 | download_file_from_google_drive(idd, fname) 398 | 399 | with open(fname) as f: 400 | content = f.readlines() 401 | content = [x.strip() for x in content] 402 | for line in content: 403 | md5 = line.split(' ')[0] 404 | scene_name = line.split(' ')[-1][0:-4] 405 | image_md5_dict.update({scene_name: md5}) 406 | # download md5 checksum file and create md5 dict for videos: 407 | video_md5_dict = {} 408 | scene_out_dir = pathname + 'videos' 409 | fname = scene_out_dir + sep + 'video_set_md5.chk' 410 | idd = id_download_dict['video_set_md5.chk'] 411 | 412 | print('\ndownloading md5 sum file for videos') 413 | download_file_from_google_drive(idd, fname) 414 | 415 | with open(fname) as f: 416 | content = f.readlines() 417 | content = [x.strip() for x in content] 418 | for line in content: 419 | md5 = line.split(' ')[0] 420 | scene_name = line.split(' ')[-1][0:-4] 421 | video_md5_dict.update({scene_name: md5}) 422 | if (len(sys.argv) == 1): 423 | print_status('both', 'both', pathname, intermediate_list, advanced_list, 424 | training_list, image_md5_dict, video_md5_dict) 425 | elif status_print and (len(sys.argv) == 2): 426 | print_status('both', 'both', pathname, intermediate_list, advanced_list, 427 | training_list, image_md5_dict, video_md5_dict) 428 | elif status_print: 429 | print_status(sequences, modality, pathname, intermediate_list, 430 | advanced_list, training_list, image_md5_dict, 431 | video_md5_dict) 432 | elif sequences or modality: 433 | for scene in scene_list: 434 | if modality == 'video': 435 | download_video(pathname, scene, video_md5_dict, calc_md5) 436 | elif modality == 'image': 437 | download_image_sets(pathname, scene, image_md5_dict, calc_md5) 438 | elif modality == 'both': 439 | download_image_sets(pathname, scene, image_md5_dict, calc_md5) 440 | download_video(pathname, scene, video_md5_dict, calc_md5) 441 | else: 442 | sys.exit('Error! Unknown modality parameter, see help [-h]') 443 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/README.md: -------------------------------------------------------------------------------- 1 | # Python Toolbox for Evaluation 2 | 3 | This Python script evaluates **training** dataset of TanksAndTemples benchmark. 4 | The script requires ``Open3D`` and a few Python packages such as ``matplotlib``, ``json``, and ``numpy``. 5 | 6 | ## How to use: 7 | **Step 0**. Reconstruct 3D models and recover camera poses from the training dataset. 8 | The raw videos of the training dataset can be found from: 9 | https://tanksandtemples.org/download/ 10 | 11 | **Step 1**. Download evaluation data (ground truth geometry + reference reconstruction) using 12 | [this link](https://drive.google.com/open?id=1UoKPiUUsKa0AVHFOrnMRhc5hFngjkE-t). In this example, we regard ``TanksAndTemples/evaluation/data/`` as a dataset folder. 13 | 14 | **Step 2**. Install Open3D. Follow instructions in http://open3d.org/docs/getting_started.html 15 | 16 | **Step 3**. Run the evaluation script and grab some coffee. 17 | ``` 18 | python run.py --dataset-dir path/to/TanksAndTemples/evaluation/data/Ignatius --traj-path path/to/TanksAndTemples/evaluation/data/Ignatius/Ignatius_COLMAP_SfM.log --ply-path path/to/TanksAndTemples/evaluation/data/Ignatius/Ignatius_COLMAP.ply 19 | ``` 20 | Output (evaluation of Ignatius): 21 | ``` 22 | =========================== 23 | Evaluating Ignatius 24 | =========================== 25 | path/to/TanksAndTemples/evaluation/data/Ignatius/Ignatius_COLMAP.ply 26 | Reading PLY: [========================================] 100% 27 | Read PointCloud: 6929586 vertices. 28 | path/to/TanksAndTemples/evaluation/data/Ignatius/Ignatius.ply 29 | Reading PLY: [========================================] 100% 30 | : 31 | ICP Iteration #0: Fitness 0.9980, RMSE 0.0044 32 | ICP Iteration #1: Fitness 0.9980, RMSE 0.0043 33 | ICP Iteration #2: Fitness 0.9980, RMSE 0.0043 34 | ICP Iteration #3: Fitness 0.9980, RMSE 0.0043 35 | ICP Iteration #4: Fitness 0.9980, RMSE 0.0042 36 | ICP Iteration #5: Fitness 0.9980, RMSE 0.0042 37 | ICP Iteration #6: Fitness 0.9979, RMSE 0.0042 38 | ICP Iteration #7: Fitness 0.9979, RMSE 0.0042 39 | ICP Iteration #8: Fitness 0.9979, RMSE 0.0042 40 | ICP Iteration #9: Fitness 0.9979, RMSE 0.0042 41 | ICP Iteration #10: Fitness 0.9979, RMSE 0.0042 42 | [EvaluateHisto] 43 | Cropping geometry: [========================================] 100% 44 | Pointcloud down sampled from 6929586 points to 1449840 points. 45 | Pointcloud down sampled from 1449840 points to 1365628 points. 46 | path/to/TanksAndTemples/evaluation/data/Ignatius/evaluation//Ignatius.precision.ply 47 | Cropping geometry: [========================================] 100% 48 | Pointcloud down sampled from 5016769 points to 4957123 points. 49 | Pointcloud down sampled from 4957123 points to 4181506 points. 50 | [compute_point_cloud_to_point_cloud_distance] 51 | [compute_point_cloud_to_point_cloud_distance] 52 | : 53 | [ViewDistances] Add color coding to visualize error 54 | [ViewDistances] Add color coding to visualize error 55 | : 56 | [get_f1_score_histo2] 57 | ============================== 58 | evaluation result : Ignatius 59 | ============================== 60 | distance tau : 0.003 61 | precision : 0.7679 62 | recall : 0.7937 63 | f-score : 0.7806 64 | ============================== 65 | ``` 66 | 67 | **Step 5**. Go to the evaluation folder. ``TanksAndTemples/evaluation/data/Ignatius/evaluation/`` will have the following outputs. 68 | 69 | 70 | 71 | ``PR_Ignatius_@d_th_0_0030.pdf`` (Precision and recall curves with a F-score) 72 | 73 | | | | 74 | |--|--| 75 | | ``Ignatius.precision.ply`` | ``Ignatius.recall.ply`` | 76 | 77 | (3D visualization of precision and recall. Each mesh is color coded using hot colormap) 78 | 79 | # Requirements 80 | 81 | - Python 3 82 | - open3d v0.9.0 83 | - matplotlib 84 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/config.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | 32 | # some global parameters - do not modify 33 | scenes_tau_dict = { 34 | "Barn": 0.01, 35 | "Caterpillar": 0.005, 36 | "Church": 0.025, 37 | "Courthouse": 0.025, 38 | "Ignatius": 0.003, 39 | "Meetingroom": 0.01, 40 | "Truck": 0.005, 41 | } 42 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/evaluation.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for downloading dataset from www.tanksandtemples.org 33 | # The dataset has a different license, please refer to 34 | # https://tanksandtemples.org/license/ 35 | 36 | import json 37 | import copy 38 | import os 39 | import numpy as np 40 | import open3d as o3d 41 | import matplotlib.pyplot as plt 42 | 43 | 44 | def read_alignment_transformation(filename): 45 | with open(filename) as data_file: 46 | data = json.load(data_file) 47 | return np.asarray(data["transformation"]).reshape((4, 4)).transpose() 48 | 49 | 50 | def write_color_distances(path, pcd, distances, max_distance): 51 | o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug) 52 | # cmap = plt.get_cmap("afmhot") 53 | cmap = plt.get_cmap("hot_r") 54 | distances = np.array(distances) 55 | colors = cmap(np.minimum(distances, max_distance) / max_distance)[:, :3] 56 | pcd.colors = o3d.utility.Vector3dVector(colors) 57 | o3d.io.write_point_cloud(path, pcd) 58 | 59 | 60 | def EvaluateHisto( 61 | source, 62 | target, 63 | trans, 64 | crop_volume, 65 | voxel_size, 66 | threshold, 67 | filename_mvs, 68 | plot_stretch, 69 | scene_name, 70 | verbose=True, 71 | ): 72 | print("[EvaluateHisto]") 73 | o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug) 74 | s = copy.deepcopy(source) 75 | s.transform(trans) 76 | s = crop_volume.crop_point_cloud(s) 77 | s = s.voxel_down_sample(voxel_size) 78 | s.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamKNN(knn=20)) 79 | print(filename_mvs + "/" + scene_name + ".precision.ply") 80 | 81 | t = copy.deepcopy(target) 82 | t = crop_volume.crop_point_cloud(t) 83 | t = t.voxel_down_sample(voxel_size) 84 | t.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamKNN(knn=20)) 85 | print("[compute_point_cloud_to_point_cloud_distance]") 86 | distance1 = s.compute_point_cloud_distance(t) 87 | print("[compute_point_cloud_to_point_cloud_distance]") 88 | distance2 = t.compute_point_cloud_distance(s) 89 | 90 | # write the distances to bin files 91 | # np.array(distance1).astype("float64").tofile( 92 | # filename_mvs + "/" + scene_name + ".precision.bin" 93 | # ) 94 | # np.array(distance2).astype("float64").tofile( 95 | # filename_mvs + "/" + scene_name + ".recall.bin" 96 | # ) 97 | 98 | # Colorize the poincloud files prith the precision and recall values 99 | # o3d.io.write_point_cloud( 100 | # filename_mvs + "/" + scene_name + ".precision.ply", s 101 | # ) 102 | # o3d.io.write_point_cloud( 103 | # filename_mvs + "/" + scene_name + ".precision.ncb.ply", s 104 | # ) 105 | # o3d.io.write_point_cloud(filename_mvs + "/" + scene_name + ".recall.ply", t) 106 | 107 | source_n_fn = filename_mvs + "/" + scene_name + ".precision.ply" 108 | target_n_fn = filename_mvs + "/" + scene_name + ".recall.ply" 109 | 110 | print("[ViewDistances] Add color coding to visualize error") 111 | # eval_str_viewDT = ( 112 | # OPEN3D_EXPERIMENTAL_BIN_PATH 113 | # + "ViewDistances " 114 | # + source_n_fn 115 | # + " --max_distance " 116 | # + str(threshold * 3) 117 | # + " --write_color_back --without_gui" 118 | # ) 119 | # os.system(eval_str_viewDT) 120 | write_color_distances(source_n_fn, s, distance1, 3 * threshold) 121 | 122 | print("[ViewDistances] Add color coding to visualize error") 123 | # eval_str_viewDT = ( 124 | # OPEN3D_EXPERIMENTAL_BIN_PATH 125 | # + "ViewDistances " 126 | # + target_n_fn 127 | # + " --max_distance " 128 | # + str(threshold * 3) 129 | # + " --write_color_back --without_gui" 130 | # ) 131 | # os.system(eval_str_viewDT) 132 | write_color_distances(target_n_fn, t, distance2, 3 * threshold) 133 | 134 | # get histogram and f-score 135 | [ 136 | precision, 137 | recall, 138 | fscore, 139 | edges_source, 140 | cum_source, 141 | edges_target, 142 | cum_target, 143 | ] = get_f1_score_histo2(threshold, filename_mvs, plot_stretch, distance1, 144 | distance2) 145 | np.savetxt(filename_mvs + "/" + scene_name + ".recall.txt", cum_target) 146 | np.savetxt(filename_mvs + "/" + scene_name + ".precision.txt", cum_source) 147 | np.savetxt( 148 | filename_mvs + "/" + scene_name + ".prf_tau_plotstr.txt", 149 | np.array([precision, recall, fscore, threshold, plot_stretch]), 150 | ) 151 | 152 | return [ 153 | precision, 154 | recall, 155 | fscore, 156 | edges_source, 157 | cum_source, 158 | edges_target, 159 | cum_target, 160 | ] 161 | 162 | 163 | def get_f1_score_histo2(threshold, 164 | filename_mvs, 165 | plot_stretch, 166 | distance1, 167 | distance2, 168 | verbose=True): 169 | print("[get_f1_score_histo2]") 170 | dist_threshold = threshold 171 | if len(distance1) and len(distance2): 172 | 173 | recall = float(sum(d < threshold for d in distance2)) / float( 174 | len(distance2)) 175 | precision = float(sum(d < threshold for d in distance1)) / float( 176 | len(distance1)) 177 | fscore = 2 * recall * precision / (recall + precision) 178 | num = len(distance1) 179 | bins = np.arange(0, dist_threshold * plot_stretch, dist_threshold / 100) 180 | hist, edges_source = np.histogram(distance1, bins) 181 | cum_source = np.cumsum(hist).astype(float) / num 182 | 183 | num = len(distance2) 184 | bins = np.arange(0, dist_threshold * plot_stretch, dist_threshold / 100) 185 | hist, edges_target = np.histogram(distance2, bins) 186 | cum_target = np.cumsum(hist).astype(float) / num 187 | 188 | else: 189 | precision = 0 190 | recall = 0 191 | fscore = 0 192 | edges_source = np.array([0]) 193 | cum_source = np.array([0]) 194 | edges_target = np.array([0]) 195 | cum_target = np.array([0]) 196 | 197 | return [ 198 | precision, 199 | recall, 200 | fscore, 201 | edges_source, 202 | cum_source, 203 | edges_target, 204 | cum_target, 205 | ] 206 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/images/f-score.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isl-org/TanksAndTemples/2a0d1b25df9352003274fbe0979a17064d768d13/python_toolbox/evaluation/images/f-score.jpg -------------------------------------------------------------------------------- /python_toolbox/evaluation/images/precision.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isl-org/TanksAndTemples/2a0d1b25df9352003274fbe0979a17064d768d13/python_toolbox/evaluation/images/precision.jpg -------------------------------------------------------------------------------- /python_toolbox/evaluation/images/recall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isl-org/TanksAndTemples/2a0d1b25df9352003274fbe0979a17064d768d13/python_toolbox/evaluation/images/recall.jpg -------------------------------------------------------------------------------- /python_toolbox/evaluation/plot.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for downloading dataset from www.tanksandtemples.org 33 | # The dataset has a different license, please refer to 34 | # https://tanksandtemples.org/license/ 35 | 36 | import matplotlib.pyplot as plt 37 | from cycler import cycler 38 | 39 | 40 | def plot_graph( 41 | scene, 42 | fscore, 43 | dist_threshold, 44 | edges_source, 45 | cum_source, 46 | edges_target, 47 | cum_target, 48 | plot_stretch, 49 | mvs_outpath, 50 | show_figure=False, 51 | ): 52 | f = plt.figure() 53 | plt_size = [14, 7] 54 | pfontsize = "medium" 55 | 56 | ax = plt.subplot(111) 57 | label_str = "precision" 58 | ax.plot( 59 | edges_source[1::], 60 | cum_source * 100, 61 | c="red", 62 | label=label_str, 63 | linewidth=2.0, 64 | ) 65 | 66 | label_str = "recall" 67 | ax.plot( 68 | edges_target[1::], 69 | cum_target * 100, 70 | c="blue", 71 | label=label_str, 72 | linewidth=2.0, 73 | ) 74 | 75 | ax.grid(True) 76 | plt.rcParams["figure.figsize"] = plt_size 77 | plt.rc("axes", prop_cycle=cycler("color", ["r", "g", "b", "y"])) 78 | plt.title("Precision and Recall: " + scene + ", " + "%02.2f f-score" % 79 | (fscore * 100)) 80 | plt.axvline(x=dist_threshold, c="black", ls="dashed", linewidth=2.0) 81 | 82 | plt.ylabel("# of points (%)", fontsize=15) 83 | plt.xlabel("Meters", fontsize=15) 84 | plt.axis([0, dist_threshold * plot_stretch, 0, 100]) 85 | ax.legend(shadow=True, fancybox=True, fontsize=pfontsize) 86 | # plt.axis([0, dist_threshold*plot_stretch, 0, 100]) 87 | 88 | plt.setp(ax.get_legend().get_texts(), fontsize=pfontsize) 89 | 90 | plt.legend(loc=2, borderaxespad=0.0, fontsize=pfontsize) 91 | plt.legend(loc=4) 92 | leg = plt.legend(loc="lower right") 93 | 94 | box = ax.get_position() 95 | ax.set_position([box.x0, box.y0, box.width * 0.8, box.height]) 96 | 97 | # Put a legend to the right of the current axis 98 | ax.legend(loc="center left", bbox_to_anchor=(1, 0.5)) 99 | plt.setp(ax.get_legend().get_texts(), fontsize=pfontsize) 100 | png_name = mvs_outpath + "/PR_{0}_@d_th_0_{1}.png".format( 101 | scene, "%04d" % (dist_threshold * 10000)) 102 | pdf_name = mvs_outpath + "/PR_{0}_@d_th_0_{1}.pdf".format( 103 | scene, "%04d" % (dist_threshold * 10000)) 104 | 105 | # save figure and display 106 | f.savefig(png_name, format="png", bbox_inches="tight") 107 | f.savefig(pdf_name, format="pdf", bbox_inches="tight") 108 | if show_figure: 109 | plt.show() 110 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/registration.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for downloading dataset from www.tanksandtemples.org 33 | # The dataset has a different license, please refer to 34 | # https://tanksandtemples.org/license/ 35 | 36 | from trajectory_io import read_trajectory, convert_trajectory_to_pointcloud 37 | import copy 38 | import numpy as np 39 | import open3d as o3d 40 | 41 | MAX_POINT_NUMBER = 4e6 42 | 43 | 44 | def read_mapping(filename): 45 | mapping = [] 46 | with open(filename, "r") as f: 47 | n_sampled_frames = int(f.readline()) 48 | n_total_frames = int(f.readline()) 49 | mapping = np.zeros(shape=(n_sampled_frames, 2)) 50 | metastr = f.readline() 51 | for iter in range(n_sampled_frames): 52 | metadata = list(map(int, metastr.split())) 53 | mapping[iter, :] = metadata 54 | metastr = f.readline() 55 | return [n_sampled_frames, n_total_frames, mapping] 56 | 57 | 58 | def gen_sparse_trajectory(mapping, f_trajectory): 59 | sparse_traj = [] 60 | for m in mapping: 61 | sparse_traj.append(f_trajectory[int(m[1] - 1)]) 62 | return sparse_traj 63 | 64 | 65 | def trajectory_alignment(map_file, traj_to_register, gt_traj_col, gt_trans, 66 | scene): 67 | traj_pcd_col = convert_trajectory_to_pointcloud(gt_traj_col) 68 | traj_pcd_col.transform(gt_trans) 69 | corres = o3d.utility.Vector2iVector( 70 | np.asarray(list(map(lambda x: [x, x], range(len(gt_traj_col)))))) 71 | rr = o3d.registration.RANSACConvergenceCriteria() 72 | rr.max_iteration = 100000 73 | rr.max_validation = 100000 74 | 75 | # in this case a log file was used which contains 76 | # every movie frame (see tutorial for details) 77 | if len(traj_to_register) > 1600: 78 | n_sampled_frames, n_total_frames, mapping = read_mapping(map_file) 79 | traj_col2 = gen_sparse_trajectory(mapping, traj_to_register) 80 | traj_to_register_pcd = convert_trajectory_to_pointcloud(traj_col2) 81 | else: 82 | traj_to_register_pcd = convert_trajectory_to_pointcloud( 83 | traj_to_register) 84 | randomvar = 0.0 85 | nr_of_cam_pos = len(traj_to_register_pcd.points) 86 | rand_number_added = np.asanyarray(traj_to_register_pcd.points) * ( 87 | np.random.rand(nr_of_cam_pos, 3) * randomvar - randomvar / 2.0 + 1) 88 | list_rand = list(rand_number_added) 89 | traj_to_register_pcd_rand = o3d.geometry.PointCloud() 90 | for elem in list_rand: 91 | traj_to_register_pcd_rand.points.append(elem) 92 | 93 | # Rough registration based on aligned colmap SfM data 94 | reg = o3d.registration.registration_ransac_based_on_correspondence( 95 | traj_to_register_pcd_rand, 96 | traj_pcd_col, 97 | corres, 98 | 0.2, 99 | o3d.registration.TransformationEstimationPointToPoint(True), 100 | 6, 101 | rr, 102 | ) 103 | return reg.transformation 104 | 105 | 106 | def crop_and_downsample( 107 | pcd, 108 | crop_volume, 109 | down_sample_method="voxel", 110 | voxel_size=0.01, 111 | trans=np.identity(4), 112 | ): 113 | pcd_copy = copy.deepcopy(pcd) 114 | pcd_copy.transform(trans) 115 | pcd_crop = crop_volume.crop_point_cloud(pcd_copy) 116 | if down_sample_method == "voxel": 117 | # return voxel_down_sample(pcd_crop, voxel_size) 118 | return pcd_crop.voxel_down_sample(voxel_size) 119 | elif down_sample_method == "uniform": 120 | n_points = len(pcd_crop.points) 121 | if n_points > MAX_POINT_NUMBER: 122 | ds_rate = int(round(n_points / float(MAX_POINT_NUMBER))) 123 | return pcd_crop.uniform_down_sample(ds_rate) 124 | return pcd_crop 125 | 126 | 127 | def registration_unif( 128 | source, 129 | gt_target, 130 | init_trans, 131 | crop_volume, 132 | threshold, 133 | max_itr, 134 | max_size=4 * MAX_POINT_NUMBER, 135 | verbose=True, 136 | ): 137 | if verbose: 138 | print("[Registration] threshold: %f" % threshold) 139 | o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug) 140 | s = crop_and_downsample(source, 141 | crop_volume, 142 | down_sample_method="uniform", 143 | trans=init_trans) 144 | t = crop_and_downsample(gt_target, 145 | crop_volume, 146 | down_sample_method="uniform") 147 | reg = o3d.registration.registration_icp( 148 | s, 149 | t, 150 | threshold, 151 | np.identity(4), 152 | o3d.registration.TransformationEstimationPointToPoint(True), 153 | o3d.registration.ICPConvergenceCriteria(1e-6, max_itr), 154 | ) 155 | reg.transformation = np.matmul(reg.transformation, init_trans) 156 | return reg 157 | 158 | 159 | def registration_vol_ds( 160 | source, 161 | gt_target, 162 | init_trans, 163 | crop_volume, 164 | voxel_size, 165 | threshold, 166 | max_itr, 167 | verbose=True, 168 | ): 169 | if verbose: 170 | print("[Registration] voxel_size: %f, threshold: %f" % 171 | (voxel_size, threshold)) 172 | o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug) 173 | s = crop_and_downsample( 174 | source, 175 | crop_volume, 176 | down_sample_method="voxel", 177 | voxel_size=voxel_size, 178 | trans=init_trans, 179 | ) 180 | t = crop_and_downsample( 181 | gt_target, 182 | crop_volume, 183 | down_sample_method="voxel", 184 | voxel_size=voxel_size, 185 | ) 186 | reg = o3d.registration.registration_icp( 187 | s, 188 | t, 189 | threshold, 190 | np.identity(4), 191 | o3d.registration.TransformationEstimationPointToPoint(True), 192 | o3d.registration.ICPConvergenceCriteria(1e-6, max_itr), 193 | ) 194 | reg.transformation = np.matmul(reg.transformation, init_trans) 195 | return reg 196 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/requirements.txt: -------------------------------------------------------------------------------- 1 | matplotlib>=1.3 2 | open3d==0.9 3 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/run.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for downloading dataset from www.tanksandtemples.org 33 | # The dataset has a different license, please refer to 34 | # https://tanksandtemples.org/license/ 35 | 36 | # this script requires Open3D python binding 37 | # please follow the intructions in setup.py before running this script. 38 | import numpy as np 39 | import open3d as o3d 40 | import os 41 | import argparse 42 | 43 | from config import scenes_tau_dict 44 | from registration import ( 45 | trajectory_alignment, 46 | registration_vol_ds, 47 | registration_unif, 48 | read_trajectory, 49 | ) 50 | from evaluation import EvaluateHisto 51 | from util import make_dir 52 | from plot import plot_graph 53 | 54 | 55 | def run_evaluation(dataset_dir, traj_path, ply_path, out_dir): 56 | scene = os.path.basename(os.path.normpath(dataset_dir)) 57 | 58 | if scene not in scenes_tau_dict: 59 | print(dataset_dir, scene) 60 | raise Exception("invalid dataset-dir, not in scenes_tau_dict") 61 | 62 | print("") 63 | print("===========================") 64 | print("Evaluating %s" % scene) 65 | print("===========================") 66 | 67 | dTau = scenes_tau_dict[scene] 68 | # put the crop-file, the GT file, the COLMAP SfM log file and 69 | # the alignment of the according scene in a folder of 70 | # the same scene name in the dataset_dir 71 | colmap_ref_logfile = os.path.join(dataset_dir, scene + "_COLMAP_SfM.log") 72 | alignment = os.path.join(dataset_dir, scene + "_trans.txt") 73 | gt_filen = os.path.join(dataset_dir, scene + ".ply") 74 | cropfile = os.path.join(dataset_dir, scene + ".json") 75 | map_file = os.path.join(dataset_dir, scene + "_mapping_reference.txt") 76 | 77 | make_dir(out_dir) 78 | 79 | # Load reconstruction and according GT 80 | print(ply_path) 81 | pcd = o3d.io.read_point_cloud(ply_path) 82 | print(gt_filen) 83 | gt_pcd = o3d.io.read_point_cloud(gt_filen) 84 | 85 | gt_trans = np.loadtxt(alignment) 86 | traj_to_register = read_trajectory(traj_path) 87 | gt_traj_col = read_trajectory(colmap_ref_logfile) 88 | 89 | trajectory_transform = trajectory_alignment(map_file, traj_to_register, 90 | gt_traj_col, gt_trans, scene) 91 | 92 | # Refine alignment by using the actual GT and MVS pointclouds 93 | vol = o3d.visualization.read_selection_polygon_volume(cropfile) 94 | # big pointclouds will be downlsampled to this number to speed up alignment 95 | dist_threshold = dTau 96 | 97 | # Registration refinment in 3 iterations 98 | r2 = registration_vol_ds(pcd, gt_pcd, trajectory_transform, vol, dTau, 99 | dTau * 80, 20) 100 | r3 = registration_vol_ds(pcd, gt_pcd, r2.transformation, vol, dTau / 2.0, 101 | dTau * 20, 20) 102 | r = registration_unif(pcd, gt_pcd, r3.transformation, vol, 2 * dTau, 20) 103 | 104 | # Histogramms and P/R/F1 105 | plot_stretch = 5 106 | [ 107 | precision, 108 | recall, 109 | fscore, 110 | edges_source, 111 | cum_source, 112 | edges_target, 113 | cum_target, 114 | ] = EvaluateHisto( 115 | pcd, 116 | gt_pcd, 117 | r.transformation, 118 | vol, 119 | dTau / 2.0, 120 | dTau, 121 | out_dir, 122 | plot_stretch, 123 | scene, 124 | ) 125 | eva = [precision, recall, fscore] 126 | print("==============================") 127 | print("evaluation result : %s" % scene) 128 | print("==============================") 129 | print("distance tau : %.3f" % dTau) 130 | print("precision : %.4f" % eva[0]) 131 | print("recall : %.4f" % eva[1]) 132 | print("f-score : %.4f" % eva[2]) 133 | print("==============================") 134 | 135 | # Plotting 136 | plot_graph( 137 | scene, 138 | fscore, 139 | dist_threshold, 140 | edges_source, 141 | cum_source, 142 | edges_target, 143 | cum_target, 144 | plot_stretch, 145 | out_dir, 146 | ) 147 | 148 | 149 | if __name__ == "__main__": 150 | parser = argparse.ArgumentParser() 151 | parser.add_argument( 152 | "--dataset-dir", 153 | type=str, 154 | required=True, 155 | help="path to a dataset/scene directory containing X.json, X.ply, ...", 156 | ) 157 | parser.add_argument( 158 | "--traj-path", 159 | type=str, 160 | required=True, 161 | help= 162 | "path to trajectory file. See `convert_to_logfile.py` to create this file.", 163 | ) 164 | parser.add_argument( 165 | "--ply-path", 166 | type=str, 167 | required=True, 168 | help="path to reconstruction ply file", 169 | ) 170 | parser.add_argument( 171 | "--out-dir", 172 | type=str, 173 | default="", 174 | help= 175 | "output directory, default: an evaluation directory is created in the directory of the ply file", 176 | ) 177 | args = parser.parse_args() 178 | 179 | if args.out_dir.strip() == "": 180 | args.out_dir = os.path.join(os.path.dirname(args.ply_path), 181 | "evaluation") 182 | 183 | run_evaluation( 184 | dataset_dir=args.dataset_dir, 185 | traj_path=args.traj_path, 186 | ply_path=args.ply_path, 187 | out_dir=args.out_dir, 188 | ) 189 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/trajectory_io.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import open3d as o3d 3 | 4 | 5 | class CameraPose: 6 | 7 | def __init__(self, meta, mat): 8 | self.metadata = meta 9 | self.pose = mat 10 | 11 | def __str__(self): 12 | return ("Metadata : " + " ".join(map(str, self.metadata)) + "\n" + 13 | "Pose : " + "\n" + np.array_str(self.pose)) 14 | 15 | 16 | def convert_trajectory_to_pointcloud(traj): 17 | pcd = o3d.geometry.PointCloud() 18 | for t in traj: 19 | pcd.points.append(t.pose[:3, 3]) 20 | return pcd 21 | 22 | 23 | def read_trajectory(filename): 24 | traj = [] 25 | with open(filename, "r") as f: 26 | metastr = f.readline() 27 | while metastr: 28 | metadata = map(int, metastr.split()) 29 | mat = np.zeros(shape=(4, 4)) 30 | for i in range(4): 31 | matstr = f.readline() 32 | mat[i, :] = np.fromstring(matstr, dtype=float, sep=" \t") 33 | traj.append(CameraPose(metadata, mat)) 34 | metastr = f.readline() 35 | return traj 36 | 37 | 38 | def write_trajectory(traj, filename): 39 | with open(filename, "w") as f: 40 | for x in traj: 41 | p = x.pose.tolist() 42 | f.write(" ".join(map(str, x.metadata)) + "\n") 43 | f.write("\n".join( 44 | " ".join(map("{0:.12f}".format, p[i])) for i in range(4))) 45 | f.write("\n") 46 | -------------------------------------------------------------------------------- /python_toolbox/evaluation/util.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def make_dir(path): 5 | if not os.path.exists(path): 6 | os.makedirs(path) 7 | -------------------------------------------------------------------------------- /python_toolbox/get_colmap_reconstruction.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ---------------------------------------------------------------------------- 4 | # - TanksAndTemples Website Toolbox - 5 | # - http://www.tanksandtemples.org - 6 | # ---------------------------------------------------------------------------- 7 | # The MIT License (MIT) 8 | # 9 | # Copyright (c) 2017 10 | # Arno Knapitsch 11 | # Jaesik Park 12 | # Qian-Yi Zhou 13 | # Vladlen Koltun 14 | # 15 | # Permission is hereby granted, free of charge, to any person obtaining a copy 16 | # of this software and associated documentation files (the "Software"), to deal 17 | # in the Software without restriction, including without limitation the rights 18 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | # copies of the Software, and to permit persons to whom the Software is 20 | # furnished to do so, subject to the following conditions: 21 | # 22 | # The above copyright notice and this permission notice shall be included in 23 | # all copies or substantial portions of the Software. 24 | # 25 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | # THE SOFTWARE. 32 | # ---------------------------------------------------------------------------- 33 | # 34 | # This script generates a COLMAP reconstruction from a numbe rof input imagess 35 | # Usage: sh get_colmap_reconstruction.sh 36 | 37 | colmap_folder=$1/ 38 | iname=$2/ 39 | outf=$3/ 40 | 41 | DATABASE=${outf}sample_reconstruction.db 42 | 43 | PROJECT_PATH=${outf} 44 | mkdir -p ${PROJECT_PATH} 45 | mkdir -p ${PROJECT_PATH}/images 46 | 47 | cp -n ${iname}*.jpg ${PROJECT_PATH}/images 48 | 49 | ${colmap_folder}/colmap feature_extractor \ 50 | --database_path ${DATABASE} \ 51 | --image_path ${PROJECT_PATH}/images \ 52 | --ImageReader.camera_model RADIAL \ 53 | --ImageReader.single_camera 1 \ 54 | --SiftExtraction.use_gpu 1 55 | 56 | ${colmap_folder}/colmap exhaustive_matcher \ 57 | --database_path ${DATABASE} \ 58 | --SiftMatching.use_gpu 1 59 | 60 | mkdir ${PROJECT_PATH}/sparse 61 | ${colmap_folder}/colmap mapper \ 62 | --database_path ${DATABASE} \ 63 | --image_path ${PROJECT_PATH}/images \ 64 | --output_path ${PROJECT_PATH}/sparse 65 | 66 | mkdir ${PROJECT_PATH}/dense 67 | 68 | ${colmap_folder}/colmap image_undistorter \ 69 | --image_path ${PROJECT_PATH}/images \ 70 | --input_path ${PROJECT_PATH}/sparse/0/ \ 71 | --output_path ${PROJECT_PATH}/dense \ 72 | --output_type COLMAP --max_image_size 1500 73 | 74 | ${colmap_folder}/colmap patch_match_stereo \ 75 | --workspace_path $PROJECT_PATH/dense \ 76 | --workspace_format COLMAP \ 77 | --PatchMatchStereo.geom_consistency true 78 | 79 | ${colmap_folder}/colmap stereo_fusion \ 80 | --workspace_path $PROJECT_PATH/dense \ 81 | --workspace_format COLMAP \ 82 | --input_type geometric \ 83 | --output_path $PROJECT_PATH/dense/fused.ply 84 | -------------------------------------------------------------------------------- /python_toolbox/interpolate_log_file.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for interpolating camera poses 33 | 34 | import sys 35 | import math 36 | import numpy as np 37 | 38 | 39 | class CameraPose: 40 | 41 | def __init__(self, meta, mat): 42 | self.metadata = meta 43 | self.pose = mat 44 | 45 | def __str__(self): 46 | return 'Metadata : ' + ' '.join(map(str, self.metadata)) + '\n' + \ 47 | "Pose : " + "\n" + np.array_str(self.pose) 48 | 49 | 50 | def read_trajectory(filename): 51 | traj = [] 52 | with open(filename, 'r') as f: 53 | metastr = f.readline() 54 | while metastr: 55 | metadata = list(map(int, metastr.split())) 56 | mat = np.zeros(shape=(4, 4)) 57 | for i in range(4): 58 | matstr = f.readline() 59 | mat[i, :] = np.fromstring(matstr, dtype=float, sep=' \t') 60 | traj.append(CameraPose(metadata, mat)) 61 | metastr = f.readline() 62 | return traj 63 | 64 | 65 | def write_trajectory(traj, filename): 66 | with open(filename, 'w') as f: 67 | for x in traj: 68 | p = x.pose.tolist() 69 | f.write(' '.join(map(str, x.metadata)) + '\n') 70 | f.write('\n'.join( 71 | ' '.join(map('{0:.12f}'.format, p[i])) for i in range(4))) 72 | f.write('\n') 73 | 74 | 75 | def read_mapping(filename): 76 | mapping = [] 77 | with open(filename, 'r') as f: 78 | n_sampled_frames = int(f.readline()) 79 | n_total_frames = int(f.readline()) 80 | mapping = np.zeros(shape=(n_sampled_frames, 2)) 81 | metastr = f.readline() 82 | for iter in range(n_sampled_frames): 83 | metadata = list(map(int, metastr.split())) 84 | mapping[iter, :] = metadata 85 | metastr = f.readline() 86 | return [n_sampled_frames, n_total_frames, mapping] 87 | 88 | 89 | def transform_matrix_4d_to_vector_6d(pose): 90 | pose_vec = list(range(6)) 91 | R = pose[0:3, 0:3] 92 | r00, r01, r02, r10, r11, r12, r20, r21, r22 = R.flat 93 | sy = math.sqrt(r00 * r00 + r10 * r10) 94 | if ~(sy < 1e-6): 95 | pose_vec[0] = math.atan2(r21, r22) 96 | pose_vec[1] = math.atan2(-r20, sy) 97 | pose_vec[2] = math.atan2(r10, r00) 98 | else: 99 | pose_vec[0] = math.atan2(-r12, r11) 100 | pose_vec[1] = math.atan2(-r20, sy) 101 | pose_vec[2] = 0 102 | pose_vec[3:] = pose[0:3, 3] 103 | return pose_vec 104 | 105 | 106 | def euler_2_rotation_matrix(x, y, z): 107 | cosx = math.cos(x) 108 | sinx = math.sin(x) 109 | Rx = np.array([[1, 0, 0], [0, cosx, -sinx], [0, sinx, cosx]]) 110 | cosy = math.cos(y) 111 | siny = math.sin(y) 112 | Ry = np.array([[cosy, 0, siny], [0, 1, 0], [-siny, 0, cosy]]) 113 | cosz = math.cos(z) 114 | sinz = math.sin(z) 115 | Rz = np.array([[cosz, -sinz, 0], [sinz, cosz, 0], [0, 0, 1]]) 116 | return Rz.dot(Ry.dot(Rx)) 117 | 118 | 119 | def transform_vector_6d_to_matrix_4d(pose_vec): 120 | pose = np.identity(4) 121 | pose[0:3, 3] = pose_vec[3:] 122 | pose[0:3, 0:3] = euler_2_rotation_matrix(pose_vec[0], pose_vec[1], 123 | pose_vec[2]) 124 | return pose 125 | 126 | 127 | if __name__ == "__main__": 128 | 129 | print('') 130 | print('==================================================================') 131 | print('Python script for interpolating camera poses') 132 | print('==================================================================') 133 | print('Algorithm : ') 134 | print(' 1) Transform n-SE(3) camera pose matrices to nx6 matrix,') 135 | print(' where each row contains euler angles and translation') 136 | print(' 2) Independently interpolate each column of nx6 matrix') 137 | print(' using 1D cubic interpolation') 138 | print('==================================================================') 139 | 140 | if len(sys.argv) != 4: 141 | print('Usage : python %s [input_log] [mapping_txt_file] [output_log]' % 142 | sys.argv[0]) 143 | print( 144 | 'Example : python %s ../test_data/test.log ../test_data/mapping.txt ../test_data/test_interpolated.log' 145 | % sys.argv[0]) 146 | print('') 147 | print('Convention of [input_log]') 148 | print('[frame ID] [frame ID] 0') 149 | print('[R t]') 150 | print('[0 1]') 151 | print(': (repeats)') 152 | print('') 153 | print('Convention of [mapping_txt_file]') 154 | print('[number of input camera poses]') 155 | print('[number of desired number of interpolated poses]') 156 | print('[Image ID] [video frame ID]') 157 | print(': (repeats)') 158 | sys.exit() 159 | 160 | # read files 161 | trajectory = read_trajectory(sys.argv[1]) 162 | n_sampled_frames, n_total_frames, mapping = read_mapping(sys.argv[2]) 163 | print('%d camera poses are loaded' % n_sampled_frames) 164 | print('Input poses are interpolated to %d poses' % n_total_frames) 165 | 166 | # make nx6 matrix 167 | n_trajectory = len(trajectory) 168 | pose_matrix = np.zeros(shape=(n_trajectory, 6)) 169 | for iter in range(n_trajectory): 170 | pose_vector = transform_matrix_4d_to_vector_6d(trajectory[iter].pose) 171 | pose_matrix[iter, :] = pose_vector 172 | 173 | # interpolation 174 | pose_frame_desired = np.linspace(1, n_total_frames, n_total_frames) 175 | pose_matrix_interpolation = np.zeros(shape=(n_total_frames, 6)) 176 | for iter in range(6): 177 | pose_element_slice = pose_matrix[:, iter] 178 | pose_frame_id = mapping[:, 1] 179 | pose_matrix_interpolation[:, iter] = np.interp(pose_frame_desired, 180 | pose_frame_id, 181 | pose_element_slice) 182 | 183 | # transform interpolated vector to SE(3) and output result 184 | traj_interpolated = [] 185 | for iter in range(n_total_frames): 186 | pose_vector = pose_matrix_interpolation[iter, :] 187 | pose = transform_vector_6d_to_matrix_4d(pose_vector) 188 | metadata = [iter, iter, n_total_frames] 189 | traj_interpolated.append(CameraPose(metadata, pose)) 190 | write_trajectory(traj_interpolated, sys.argv[3]) 191 | -------------------------------------------------------------------------------- /python_toolbox/upload_t2_results.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # - TanksAndTemples Website Toolbox - 3 | # - http://www.tanksandtemples.org - 4 | # ---------------------------------------------------------------------------- 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2017 8 | # Arno Knapitsch 9 | # Jaesik Park 10 | # Qian-Yi Zhou 11 | # Vladlen Koltun 12 | # 13 | # Permission is hereby granted, free of charge, to any person obtaining a copy 14 | # of this software and associated documentation files (the "Software"), to deal 15 | # in the Software without restriction, including without limitation the rights 16 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | # copies of the Software, and to permit persons to whom the Software is 18 | # furnished to do so, subject to the following conditions: 19 | # 20 | # The above copyright notice and this permission notice shall be included in 21 | # all copies or substantial portions of the Software. 22 | # 23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | # THE SOFTWARE. 30 | # ---------------------------------------------------------------------------- 31 | # 32 | # This python script is for uploading results to www.tanksandtemples.org 33 | # 34 | # Requirements: 35 | # sudo pip install requests (requests is not included in python 2.7) 36 | 37 | import json, os, sys 38 | import datetime 39 | import base64 40 | import time 41 | import sys 42 | import os 43 | import argparse 44 | import zipfile 45 | import hashlib 46 | import requests 47 | 48 | if (sys.version_info > (3, 0)): 49 | pversion = 3 50 | from urllib.request import Request, urlopen 51 | else: 52 | pversion = 2 53 | from urllib2 import urlopen 54 | 55 | sep = os.sep 56 | parser = argparse.ArgumentParser(description='Tanks and Temples file uploader') 57 | 58 | # Optional arguments 59 | parser.add_argument( 60 | '--group', 61 | type=str, 62 | help= 63 | '(intermediate|advanced|both) choose if you want to download intermediate or advanced dataset', 64 | default='both') 65 | parser.add_argument('--pathname', 66 | type=str, 67 | help='chose destination path name, default = local path', 68 | default='') 69 | parser.add_argument('--send_md5_off', 70 | action='store_false', 71 | default=True, 72 | dest='send_md5', 73 | help='do not calculate md5sum after download') 74 | 75 | GCS_API_ENDPOINT = 'https://storage.googleapis.com' 76 | 77 | 78 | def Base64Sign(plaintext, key): 79 | """Signs and returns a base64-encoded SHA256 digest.""" 80 | shahash = SHA256.new(plaintext) 81 | signer = PKCS1_v1_5.new(key) 82 | signature_bytes = signer.sign(shahash) 83 | return base64.b64encode(signature_bytes) 84 | 85 | 86 | def submit_file(filename, credentials_upload): 87 | with open(credentials_upload) as f: 88 | content = f.readlines() 89 | credential_content = [x.strip() for x in content] 90 | 91 | signature_dict = {} 92 | policy_dict = {} 93 | for signatureline in credential_content[0:-1]: 94 | signaturelinecontent = signatureline.split('###') 95 | signature_dict[signaturelinecontent[2]] = signaturelinecontent[1] 96 | policy_dict[signaturelinecontent[2]] = signaturelinecontent[0] 97 | 98 | access_str = credential_content[-1] 99 | access_info = access_str.split('###') 100 | fsignature = signature_dict[filename] 101 | fpolicy = policy_dict[filename] 102 | gcs_filename = access_info[1] + filename 103 | client_id_email = access_info[2] 104 | expiration = access_info[3] 105 | 106 | files = {'file': open(filename, 'rb')} 107 | gs_acl = 'bucket-owner-read' 108 | headers = {'enctype': 'multipart/form-data'} 109 | bucket_name = 't2-website-userdata' 110 | policy = {} 111 | policy['key'] = gcs_filename 112 | policy['bucket'] = 't2-website-userdata' 113 | policy['acl'] = gs_acl 114 | 115 | policy['GoogleAccessId'] = client_id_email 116 | policy['bucket'] = bucket_name 117 | policy['policy'] = fpolicy 118 | policy['signature'] = fsignature 119 | url = 'http://{bucket_name}.storage.googleapis.com'.format( 120 | bucket_name=bucket_name) 121 | session = requests.Session() 122 | print('start %s upload' % filename) 123 | r = session.post(url, data=policy, files=files, headers=headers) 124 | ProcessResponse(r, 204) 125 | 126 | 127 | def ProcessResponse(r, expected_status=200): 128 | if r.status_code != expected_status: 129 | sys.exit('Exiting due to receiving %d status code when expecting %d.' % 130 | (r.status_code, expected_status)) 131 | else: 132 | print('upload finished') 133 | 134 | 135 | def generate_file_md5(filename, blocksize=2**20): 136 | m = hashlib.md5() 137 | with open(filename, "rb") as f: 138 | while True: 139 | buf = f.read(blocksize) 140 | if not buf: 141 | break 142 | m.update(buf) 143 | return m.digest() 144 | 145 | 146 | def generate_file_md5X(filename, blocksize=2**20): 147 | m = hashlib.md5() 148 | with open(filename, "r") as f: 149 | while True: 150 | buf = f.read(blocksize) 151 | if not buf: 152 | break 153 | m.update(buf) 154 | return m.digest() 155 | 156 | 157 | def generate_md5_file(md5_check_fn, scene_list): 158 | md5_check = open(md5_check_fn, 'w') 159 | for scene in scene_list: 160 | ply_file = scene + '.ply' 161 | log_file = scene + '.log' 162 | if os.path.isfile(ply_file): 163 | md5_ply_file = generate_file_md5(ply_file, blocksize=2**20) 164 | else: 165 | md5_ply_file = ''.encode('ascii') 166 | if os.path.isfile(log_file): 167 | md5_log_file = generate_file_md5(log_file, blocksize=2**20) 168 | else: 169 | md5_log_file = ''.encode('ascii') 170 | content_md5_log = base64.b64encode(md5_log_file) 171 | content_md5_ply = base64.b64encode(md5_ply_file) 172 | print('md5_ply_file: ', ply_file, content_md5_ply) 173 | print('md5_log_file: ', log_file, content_md5_log) 174 | md5_check.write("%s###%s\n" % 175 | (ply_file, content_md5_ply.decode('UTF-8'))) 176 | md5_check.write("%s###%s\n" % 177 | (log_file, content_md5_log.decode('UTF-8'))) 178 | md5_check.close() 179 | 180 | 181 | def check_filestatus(scene_list): 182 | for scene in scene_list: 183 | ply_file = scene + '.ply' 184 | log_file = scene + '.log' 185 | if not os.path.isfile(ply_file): 186 | sys.exit('Error! %s is missing.' % ply_file) 187 | if not os.path.isfile(log_file): 188 | sys.exit('Error! %s is missing.' % log_file) 189 | 190 | 191 | intermediate_list = [ 192 | 'Family', 'Francis', 'Horse', 'Lighthouse', 'M60', 'Panther', 'Playground', 193 | 'Train' 194 | ] 195 | advanced_list = [ 196 | 'Auditorium', 'Ballroom', 'Courtroom', 'Museum', 'Palace', 'Temple' 197 | ] 198 | both_list = intermediate_list + advanced_list 199 | both_list.sort() 200 | 201 | args = parser.parse_args() 202 | sequences = args.group 203 | send_md5 = args.send_md5 204 | 205 | if sequences == 'intermediate': 206 | scene_list = intermediate_list 207 | elif sequences == 'advanced': 208 | scene_list = advanced_list 209 | elif sequences == 'both': 210 | scene_list = intermediate_list + advanced_list 211 | elif sequences == '': 212 | scene_list = intermediate_list + advanced_list 213 | else: 214 | sys.exit('Error! Unknown group parameter, see help [-h]') 215 | 216 | scene_list.sort() 217 | 218 | check_filestatus(scene_list) 219 | 220 | credentials_upload = 't2_submission_credentials.txt' 221 | md5_check_fn = 'md5_check.txt' 222 | generate_md5_file(md5_check_fn, both_list) 223 | 224 | if send_md5: 225 | submit_file(md5_check_fn, credentials_upload) 226 | 227 | for scene in scene_list: 228 | ply_file = scene + '.ply' 229 | log_file = scene + '.log' 230 | submit_file(ply_file, credentials_upload) 231 | submit_file(log_file, credentials_upload) 232 | -------------------------------------------------------------------------------- /test_data/Ignatius_mapping.txt: -------------------------------------------------------------------------------- 1 | 263 2 | 7845 3 | 0 1 4 | 1 30 5 | 2 60 6 | 3 90 7 | 4 120 8 | 5 150 9 | 6 180 10 | 7 210 11 | 8 240 12 | 9 270 13 | 10 300 14 | 11 330 15 | 12 360 16 | 13 390 17 | 14 420 18 | 15 450 19 | 16 480 20 | 17 510 21 | 18 540 22 | 19 570 23 | 20 600 24 | 21 630 25 | 22 660 26 | 23 690 27 | 24 720 28 | 25 750 29 | 26 780 30 | 27 810 31 | 28 840 32 | 29 870 33 | 30 900 34 | 31 930 35 | 32 960 36 | 33 990 37 | 34 1019 38 | 35 1049 39 | 36 1079 40 | 37 1109 41 | 38 1139 42 | 39 1169 43 | 40 1199 44 | 41 1229 45 | 42 1259 46 | 43 1289 47 | 44 1319 48 | 45 1349 49 | 46 1379 50 | 47 1409 51 | 48 1439 52 | 49 1469 53 | 50 1499 54 | 51 1529 55 | 52 1559 56 | 53 1589 57 | 54 1619 58 | 55 1649 59 | 56 1679 60 | 57 1709 61 | 58 1739 62 | 59 1769 63 | 60 1799 64 | 61 1829 65 | 62 1859 66 | 63 1889 67 | 64 1919 68 | 65 1949 69 | 66 1979 70 | 67 2008 71 | 68 2038 72 | 69 2068 73 | 70 2098 74 | 71 2128 75 | 72 2158 76 | 73 2188 77 | 74 2218 78 | 75 2248 79 | 76 2278 80 | 77 2308 81 | 78 2338 82 | 79 2368 83 | 80 2398 84 | 81 2428 85 | 82 2458 86 | 83 2488 87 | 84 2518 88 | 85 2548 89 | 86 2578 90 | 87 2608 91 | 88 2638 92 | 89 2668 93 | 90 2698 94 | 91 2728 95 | 92 2758 96 | 93 2788 97 | 94 2818 98 | 95 2848 99 | 96 2878 100 | 97 2908 101 | 98 2938 102 | 99 2968 103 | 100 2998 104 | 101 3027 105 | 102 3057 106 | 103 3087 107 | 104 3117 108 | 105 3147 109 | 106 3177 110 | 107 3207 111 | 108 3237 112 | 109 3267 113 | 110 3297 114 | 111 3327 115 | 112 3357 116 | 113 3387 117 | 114 3417 118 | 115 3447 119 | 116 3477 120 | 117 3507 121 | 118 3537 122 | 119 3567 123 | 120 3597 124 | 121 3627 125 | 122 3657 126 | 123 3687 127 | 124 3717 128 | 125 3747 129 | 126 3777 130 | 127 3807 131 | 128 3837 132 | 129 3867 133 | 130 3897 134 | 131 3927 135 | 132 3957 136 | 133 3987 137 | 134 4016 138 | 135 4046 139 | 136 4076 140 | 137 4106 141 | 138 4136 142 | 139 4166 143 | 140 4196 144 | 141 4226 145 | 142 4256 146 | 143 4286 147 | 144 4316 148 | 145 4346 149 | 146 4376 150 | 147 4406 151 | 148 4436 152 | 149 4466 153 | 150 4496 154 | 151 4526 155 | 152 4556 156 | 153 4586 157 | 154 4616 158 | 155 4646 159 | 156 4676 160 | 157 4706 161 | 158 4736 162 | 159 4766 163 | 160 4796 164 | 161 4826 165 | 162 4856 166 | 163 4886 167 | 164 4916 168 | 165 4946 169 | 166 4976 170 | 167 5005 171 | 168 5035 172 | 169 5065 173 | 170 5095 174 | 171 5125 175 | 172 5155 176 | 173 5185 177 | 174 5215 178 | 175 5245 179 | 176 5275 180 | 177 5305 181 | 178 5335 182 | 179 5365 183 | 180 5395 184 | 181 5425 185 | 182 5455 186 | 183 5485 187 | 184 5515 188 | 185 5545 189 | 186 5575 190 | 187 5605 191 | 188 5635 192 | 189 5665 193 | 190 5695 194 | 191 5725 195 | 192 5755 196 | 193 5785 197 | 194 5815 198 | 195 5845 199 | 196 5875 200 | 197 5905 201 | 198 5935 202 | 199 5965 203 | 200 5995 204 | 201 6024 205 | 202 6054 206 | 203 6084 207 | 204 6114 208 | 205 6144 209 | 206 6174 210 | 207 6204 211 | 208 6234 212 | 209 6264 213 | 210 6294 214 | 211 6324 215 | 212 6354 216 | 213 6384 217 | 214 6414 218 | 215 6444 219 | 216 6474 220 | 217 6504 221 | 218 6534 222 | 219 6564 223 | 220 6594 224 | 221 6624 225 | 222 6654 226 | 223 6684 227 | 224 6714 228 | 225 6744 229 | 226 6774 230 | 227 6804 231 | 228 6834 232 | 229 6864 233 | 230 6894 234 | 231 6924 235 | 232 6954 236 | 233 6984 237 | 234 7013 238 | 235 7043 239 | 236 7073 240 | 237 7103 241 | 238 7133 242 | 239 7163 243 | 240 7193 244 | 241 7223 245 | 242 7253 246 | 243 7283 247 | 244 7313 248 | 245 7343 249 | 246 7373 250 | 247 7403 251 | 248 7433 252 | 249 7463 253 | 250 7493 254 | 251 7523 255 | 252 7553 256 | 253 7583 257 | 254 7613 258 | 255 7643 259 | 256 7673 260 | 257 7703 261 | 258 7733 262 | 259 7763 263 | 260 7793 264 | 261 7823 265 | 262 7845 266 | -------------------------------------------------------------------------------- /test_data/mapping.txt: -------------------------------------------------------------------------------- 1 | 151 2 | 6015 3 | 0 1 4 | 1 41 5 | 2 81 6 | 3 121 7 | 4 161 8 | 5 201 9 | 6 241 10 | 7 281 11 | 8 321 12 | 9 361 13 | 10 401 14 | 11 441 15 | 12 481 16 | 13 521 17 | 14 561 18 | 15 601 19 | 16 641 20 | 17 681 21 | 18 721 22 | 19 761 23 | 20 801 24 | 21 841 25 | 22 881 26 | 23 921 27 | 24 961 28 | 25 1001 29 | 26 1041 30 | 27 1081 31 | 28 1121 32 | 29 1161 33 | 30 1201 34 | 31 1241 35 | 32 1281 36 | 33 1321 37 | 34 1361 38 | 35 1401 39 | 36 1441 40 | 37 1481 41 | 38 1521 42 | 39 1561 43 | 40 1601 44 | 41 1641 45 | 42 1681 46 | 43 1721 47 | 44 1761 48 | 45 1801 49 | 46 1841 50 | 47 1881 51 | 48 1921 52 | 49 1961 53 | 50 2001 54 | 51 2041 55 | 52 2081 56 | 53 2121 57 | 54 2161 58 | 55 2201 59 | 56 2241 60 | 57 2281 61 | 58 2321 62 | 59 2361 63 | 60 2401 64 | 61 2441 65 | 62 2481 66 | 63 2521 67 | 64 2561 68 | 65 2601 69 | 66 2641 70 | 67 2681 71 | 68 2721 72 | 69 2761 73 | 70 2801 74 | 71 2841 75 | 72 2881 76 | 73 2921 77 | 74 2961 78 | 75 3001 79 | 76 3041 80 | 77 3081 81 | 78 3121 82 | 79 3161 83 | 80 3201 84 | 81 3241 85 | 82 3281 86 | 83 3321 87 | 84 3361 88 | 85 3401 89 | 86 3441 90 | 87 3481 91 | 88 3521 92 | 89 3561 93 | 90 3601 94 | 91 3641 95 | 92 3681 96 | 93 3721 97 | 94 3761 98 | 95 3801 99 | 96 3841 100 | 97 3881 101 | 98 3921 102 | 99 3961 103 | 100 4001 104 | 101 4041 105 | 102 4081 106 | 103 4121 107 | 104 4161 108 | 105 4201 109 | 106 4241 110 | 107 4281 111 | 108 4321 112 | 109 4361 113 | 110 4401 114 | 111 4441 115 | 112 4481 116 | 113 4521 117 | 114 4561 118 | 115 4601 119 | 116 4641 120 | 117 4681 121 | 118 4721 122 | 119 4761 123 | 120 4801 124 | 121 4841 125 | 122 4881 126 | 123 4921 127 | 124 4961 128 | 125 5001 129 | 126 5041 130 | 127 5081 131 | 128 5121 132 | 129 5161 133 | 130 5201 134 | 131 5241 135 | 132 5281 136 | 133 5321 137 | 134 5361 138 | 135 5401 139 | 136 5441 140 | 137 5481 141 | 138 5521 142 | 139 5561 143 | 140 5601 144 | 141 5641 145 | 142 5681 146 | 143 5721 147 | 144 5761 148 | 145 5801 149 | 146 5841 150 | 147 5881 151 | 148 5921 152 | 149 5961 153 | 150 6001 154 | -------------------------------------------------------------------------------- /test_data/test.log: -------------------------------------------------------------------------------- 1 | 0 0 0 2 | 0.753603734645 -0.022161615602 -0.656955193301 2.377286677636 3 | 0.132899187479 0.983928390102 0.119259043560 -0.005093510202 4 | 0.643753888671 -0.177182889403 0.744437372183 -2.085496122745 5 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 6 | 1 1 0 7 | 0.690432118672 -0.002989524853 -0.723391018436 2.411619293586 8 | 0.135383075708 0.982857137118 0.125152992632 -0.000777690477 9 | 0.710615877690 -0.184344545605 0.679000866479 -1.981468715835 10 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 11 | 2 2 0 12 | 0.641435850734 0.009373780820 -0.767119202262 2.450532124670 13 | 0.135200011599 0.982894234163 0.125059451738 -0.011560408414 14 | 0.755169315524 -0.183932166405 0.629196266108 -1.782977930760 15 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 16 | 3 3 0 17 | 0.560765904644 0.019268492763 -0.827749761919 2.677891626484 18 | 0.137115232339 0.983764240854 0.115789926988 0.016613816093 19 | 0.816541705139 -0.178428190928 0.549019443975 -1.531434856128 20 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 21 | 4 4 0 22 | 0.515530786569 0.025479103108 -0.856492583179 2.720748427069 23 | 0.133516703729 0.984960259043 0.109665857651 0.028023127466 24 | 0.846405351803 -0.170892146729 0.504375448330 -1.293013997190 25 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 26 | 5 5 0 27 | 0.519662894601 0.021261525885 -0.854106274682 2.967582372365 28 | 0.131687092246 0.985750795702 0.104660651429 0.058677339816 29 | 0.844161175766 -0.166863086807 0.509458247097 -1.118909504739 30 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 31 | 6 6 0 32 | 0.522223112027 0.024438881427 -0.852458166555 2.942001998675 33 | 0.125063429761 0.986587715993 0.104898969021 0.075142982835 34 | 0.843588361221 -0.161392057549 0.512162499938 -1.091521146762 35 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 36 | 7 7 0 37 | 0.541386881201 0.044363066289 -0.839602429903 2.926839676830 38 | 0.078577320086 0.991566529404 0.103060292799 0.075795662218 39 | 0.837093738310 -0.121769197801 0.533335179965 -1.079246366599 40 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 41 | 8 8 0 42 | 0.497043477948 0.051919886582 -0.866170608956 3.011801844102 43 | 0.075346930371 0.991855560788 0.102690686937 0.066324656827 44 | 0.864447822905 -0.116305040635 0.489083333584 -0.986631177073 45 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 46 | 9 9 0 47 | 0.319790900253 0.068203219598 -0.945029849386 3.184660872922 48 | 0.077288073538 0.992204237013 0.097761433578 0.015786226751 49 | 0.944330264835 -0.104302756642 0.312026590753 -0.784617256105 50 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 51 | 10 10 0 52 | 0.258129767503 0.007162352091 -0.966083905627 3.386682025837 53 | 0.075207919710 0.996789018510 0.027484960854 -0.059333894173 54 | 0.963178685817 -0.079751833664 0.256762251514 -0.436090311247 55 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 56 | 11 11 0 57 | 0.205097401524 -0.056025327040 -0.977136401903 3.465471746751 58 | 0.081950330273 0.995837541025 -0.039896512895 -0.038117916439 59 | 0.975304326127 -0.071894026894 0.208834989392 0.013886990488 60 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 61 | 12 12 0 62 | 0.077381103596 -0.073457572441 -0.994292783082 3.563919511765 63 | 0.089737959060 0.993747311380 -0.066433374943 0.021567091421 64 | 0.992955815805 -0.084084954978 0.083489182957 0.469465065828 65 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 66 | 13 13 0 67 | -0.052048861871 -0.079699702559 -0.995459288892 3.480404076938 68 | 0.097874264277 0.991604224982 -0.084508531893 0.053369860332 69 | 0.993836941767 -0.101828389865 -0.043811324135 0.982630804309 70 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 71 | 14 14 0 72 | -0.238583873224 -0.072185805932 -0.968434684192 3.240955470848 73 | 0.098188232702 0.990330036475 -0.098007552711 0.089009012267 74 | 0.966144709184 -0.118472017166 -0.229188969870 1.403638962496 75 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 76 | 15 15 0 77 | -0.421437822984 -0.062402485279 -0.904707394561 3.004222935055 78 | 0.095757127695 0.988990245435 -0.112822258961 0.136194300865 79 | 0.901787176910 -0.134179802699 -0.410822408510 1.857102628351 80 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 81 | 16 16 0 82 | -0.536565816758 -0.052595229469 -0.842217717801 2.721528652140 83 | 0.095940796620 0.987782124558 -0.122808128807 0.151300566812 84 | 0.838386728118 -0.146697698668 -0.524964092818 2.210263129024 85 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 86 | 17 17 0 87 | -0.645513668280 -0.039450893667 -0.762729181383 2.443318516502 88 | 0.092261056120 0.987323726708 -0.129150132660 0.176088422585 89 | 0.758155706084 -0.153738369418 -0.633691180036 2.523749943365 90 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 91 | 18 18 0 92 | -0.764201348539 -0.027268005142 -0.644400037234 2.056198677121 93 | 0.080945528162 0.987151642536 -0.137765911240 0.220767172007 94 | 0.639877155056 -0.157442309196 -0.752175383866 2.919487354878 95 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 96 | 19 19 0 97 | -0.837842572967 -0.013683832564 -0.545738346216 1.594258295537 98 | 0.074341846570 0.987512906994 -0.138893963858 0.237665433871 99 | 0.540824259490 -0.156942652182 -0.826363058893 3.189849652121 100 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 101 | 20 20 0 102 | -0.907590722699 0.000734318350 -0.419856447837 1.213305399825 103 | 0.062159163665 0.989213608602 -0.132637400438 0.254960296292 104 | 0.415230314869 -0.146478334231 -0.897846743371 3.285573828610 105 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 106 | 21 21 0 107 | -0.961521644339 0.009829142562 -0.274559583719 0.816751714221 108 | 0.046388372103 0.990819554603 -0.126983248086 0.269756625890 109 | 0.270790871317 -0.134833283418 -0.953150420742 3.423048957337 110 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 111 | 22 22 0 112 | -0.997128490549 0.017386790695 -0.073726778912 0.453587692329 113 | 0.025888089813 0.992915271306 -0.115970177376 0.244852039284 114 | 0.071188097496 -0.117545628350 -0.990514227375 3.261834337076 115 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 116 | 23 23 0 117 | -0.989787319156 0.020990719403 0.141011045563 0.074217103027 118 | 0.006329985527 0.994596512768 -0.103622960870 0.251412340302 119 | -0.142424213374 -0.101671905830 -0.984571896737 3.220998900005 120 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 121 | 24 24 0 122 | -0.959958065908 0.021167436225 0.279348888229 -0.203496831426 123 | -0.005265202982 0.995602129420 -0.093534405694 0.236477922869 124 | -0.280100230898 -0.091259777857 -0.955624851186 3.116918516498 125 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 126 | 25 25 0 127 | -0.947985042890 -0.019983779933 0.317690639878 -0.472531483507 128 | -0.050506492136 0.994827483727 -0.088132729872 0.234148001139 129 | -0.314286156836 -0.099593836969 -0.944090890889 3.055110713556 130 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 131 | 26 26 0 132 | -0.939151843139 -0.056208714103 0.338876035993 -0.719268534186 133 | -0.093614714159 0.991060396512 -0.095055707954 0.183071665299 134 | -0.330503665039 -0.120995383303 -0.936018168756 2.913728498905 135 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 136 | 27 27 0 137 | -0.909608326026 -0.060490658652 0.411042157130 -1.066925905564 138 | -0.111533008588 0.988581010329 -0.101331073509 0.158664730926 139 | -0.400218893504 -0.138016226144 -0.905968231305 2.856840957920 140 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 141 | 28 28 0 142 | -0.885322078810 -0.051533173120 0.462114919417 -1.335066127027 143 | -0.115425469706 0.987088353316 -0.111056521111 0.138197852111 144 | -0.450425163176 -0.151660548616 -0.879839358761 2.712860482301 145 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 146 | 29 29 0 147 | -0.822420212855 -0.035995367512 0.567740572632 -1.710515086632 148 | -0.121633458559 0.986043678190 -0.113680106862 0.120672944862 149 | -0.555725045372 -0.162549064762 -0.815320492922 2.582767372624 150 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 151 | 30 30 0 152 | -0.770602944533 -0.016626396936 0.637100827149 -2.160192527253 153 | -0.122580808062 0.984861292569 -0.122565100366 0.104671167088 154 | -0.625418137348 -0.172545128177 -0.760975108759 2.399920204845 155 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 156 | 31 31 0 157 | -0.721539219210 -0.002577181970 0.692369125061 -2.439465959492 158 | -0.122380685314 0.984722744197 -0.123871260955 0.079795939160 159 | -0.681472387604 -0.174110538341 -0.710831480995 2.101308506979 160 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 161 | 32 32 0 162 | -0.580388897483 0.016713366685 0.814167679724 -2.760809155334 163 | -0.133406460075 0.984330757108 -0.115306865579 0.070637108521 164 | -0.803337453218 -0.175538087643 -0.569064968543 1.875044618147 165 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 166 | 33 33 0 167 | -0.487225007535 0.034100658291 0.872610571872 -3.048723462226 168 | -0.132832672965 0.984716024317 -0.112649168887 0.024929383026 169 | -0.863115024798 -0.170796660863 -0.475248593279 1.558519779414 170 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 171 | 34 34 0 172 | -0.350256354753 0.048172609620 0.935413834290 -3.177000379653 173 | -0.135482464664 0.985568448966 -0.101485590835 0.004403165506 174 | -0.926803184860 -0.162278227316 -0.338675060281 1.206939113777 175 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 176 | 35 35 0 177 | -0.228058968078 0.059424975702 0.971831104581 -3.307050675251 178 | -0.134357404000 0.986665845846 -0.091861711329 -0.030777437635 179 | -0.964331432423 -0.151522797891 -0.217033788509 0.873115027926 180 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 181 | 36 36 0 182 | -0.146842192900 0.064597368160 0.987048582420 -3.488867844484 183 | -0.128024351547 0.988231044663 -0.083720794333 -0.062510780922 184 | -0.980840195670 -0.138659965453 -0.136843980876 0.510308409636 185 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 186 | 37 37 0 187 | -0.084523112547 0.069327984297 0.994005819625 -3.671358489100 188 | -0.125383991181 0.988907090703 -0.079634171262 -0.126564307247 189 | -0.988500274967 -0.131363530214 -0.074892867758 0.083989097804 190 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 191 | 38 38 0 192 | 0.042825591019 0.073977795532 0.996339450515 -3.643713008253 193 | -0.124542520956 0.989871453749 -0.068144371982 -0.149985956221 194 | -0.991289148210 -0.121168398220 0.051605220611 -0.266488757678 195 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 196 | 39 39 0 197 | 0.197743640113 0.077052669345 0.977220924053 -3.656670535742 198 | -0.123961473992 0.990868211397 -0.053044746299 -0.173918653853 199 | -0.972384389645 -0.110648444594 0.205489445301 -0.604468861227 200 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 201 | 40 40 0 202 | 0.326396751567 0.073107731686 0.942401497942 -3.457988371532 203 | -0.118462353657 0.992307537146 -0.035950303919 -0.197532560536 204 | -0.937780355159 -0.099905020663 0.332546468969 -0.950659671684 205 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 206 | 41 41 0 207 | 0.458654189118 0.070920692361 0.885780782672 -3.215340283367 208 | -0.113672127175 0.993303272401 -0.020670485488 -0.206585653434 209 | -0.881314919344 -0.091207877193 0.463644402067 -1.304678876392 210 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 211 | 42 42 0 212 | 0.589539853752 0.070165581402 0.804685978314 -2.866753399797 213 | -0.107010210151 0.994223333182 -0.008293267219 -0.217679435882 214 | -0.800619477300 -0.081220407190 0.593642712393 -1.516027907203 215 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 216 | 43 43 0 217 | 0.700441375741 0.068834571359 0.710383118356 -2.522229091300 218 | -0.098839106589 0.995102895592 0.001032602319 -0.223742601624 219 | -0.706833222244 -0.070936852514 0.703814781910 -1.795417678873 220 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 221 | 44 44 0 222 | 0.773321045360 0.067576249152 0.630402786851 -2.204102321701 223 | -0.091126323035 0.995826596621 0.005037508889 -0.237895310717 224 | -0.627431443561 -0.061341941575 0.776251645097 -2.004103143377 225 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 226 | 45 45 0 227 | 0.873556774895 0.066912924957 0.482101046138 -1.894141313995 228 | -0.082475344945 0.996530948370 0.011130670531 -0.239034386292 229 | -0.479683828880 -0.049484692825 0.876045023263 -2.119597019844 230 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 231 | 46 46 0 232 | 0.975936964577 0.064202861323 0.208386742722 -1.618130758130 233 | -0.067380482461 0.997693831646 0.008178566629 -0.221767300908 234 | -0.207381080448 -0.022022964532 0.978012309335 -2.253488268163 235 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 236 | 47 47 0 237 | 0.995656601273 0.054512343151 0.075474072822 -1.516263292511 238 | -0.053920900839 0.998496591646 -0.009853554579 -0.218534888083 239 | -0.075897744873 0.005741126138 0.997099077849 -2.501180507045 240 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 241 | 48 48 0 242 | 0.999696587706 0.002902791251 0.024460294033 -1.272795281661 243 | -0.002589841403 0.999914515536 -0.012816171204 -0.211276014353 244 | -0.024495405747 0.012748934299 0.999618646953 -2.630367900360 245 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 246 | 49 49 0 247 | 0.999676559787 -0.005567173450 -0.024814967363 -1.193687741069 248 | 0.005069912913 0.999785987361 -0.020056809316 -0.231469713463 249 | 0.024921316347 0.019924512458 0.999490841444 -2.915368251866 250 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 251 | 50 50 0 252 | 0.999944257405 -0.006993687679 0.007910141434 -0.871250219670 253 | 0.007180747385 0.999689228164 -0.023872233285 -0.232661824780 254 | -0.007740728122 0.023927703352 0.999683722832 -3.028570311301 255 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 256 | 51 51 0 257 | 0.999306950018 -0.011935909840 -0.035258382167 -0.640516914488 258 | 0.011035693884 0.999610911267 -0.025617170636 -0.227839788155 259 | 0.035550427806 0.025210315888 0.999049852008 -3.221300912669 260 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 261 | 52 52 0 262 | 0.996177835693 -0.019854922980 -0.085061717973 -0.243893844446 263 | 0.018266075826 0.999644610482 -0.019416556479 -0.251622155638 264 | 0.085417002435 0.017788598176 0.996186476339 -3.333413697772 265 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 266 | 53 53 0 267 | 0.986016442569 -0.024044741128 -0.164904222877 0.126815136525 268 | 0.023752483657 0.999710857873 -0.003744289234 -0.248658414064 269 | 0.164946572619 -0.000224957328 0.986302466465 -3.515177886189 270 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 271 | 54 54 0 272 | 0.974194638844 -0.014236235913 -0.225260041332 0.488611599231 273 | 0.026721061761 0.998264800777 0.052472555619 -0.202453007026 274 | 0.224122157522 -0.057137674278 0.972884624806 -3.471986130323 275 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 276 | 55 55 0 277 | 0.954330619447 -0.000298414226 -0.298752442522 0.924389430799 278 | 0.028053481328 0.995670453946 0.088619147608 -0.202033259389 279 | 0.297432535459 -0.092953010098 0.950207172542 -3.500428797971 280 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 281 | 56 56 0 282 | 0.924802859446 0.013893766169 -0.380192878161 1.372485976185 283 | 0.022169839938 0.995666657690 0.090312814128 -0.219973288600 284 | 0.379800157372 -0.091950364111 0.920487349516 -3.469992458518 285 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 286 | 57 57 0 287 | 0.887191797652 0.021715031723 -0.460889670175 1.874156276528 288 | 0.019669859242 0.996203804060 0.084800243717 -0.181315259771 289 | 0.460981482615 -0.084299715861 0.883396712134 -3.405724269184 290 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 291 | 58 58 0 292 | 0.844973589725 0.025935991199 -0.534178847607 2.368107878013 293 | 0.017835333835 0.996901234302 0.076614826222 -0.181239721134 294 | 0.534510633886 -0.074264763452 0.841892637484 -3.211575246908 295 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 296 | 59 59 0 297 | 0.786307326905 0.032853149714 -0.616961151558 2.723922417761 298 | 0.015755255259 0.997194269376 0.073180296939 -0.157796933555 299 | 0.617634328636 -0.067262578617 0.783583550674 -2.974815444843 300 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 301 | 60 60 0 302 | 0.688021075111 0.037268048748 -0.724732658263 3.080034437699 303 | 0.019178679238 0.997397822510 0.069496448495 -0.107239328032 304 | 0.725436773036 -0.061714428080 0.685515970308 -2.635143540187 305 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 306 | 61 61 0 307 | 0.600106020759 0.040970603563 -0.798870563989 3.268085825335 308 | 0.018715853023 0.997694943062 0.065226662188 -0.078054829196 309 | 0.799701497566 -0.054094456816 0.597955942417 -2.227741378613 310 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 311 | 62 62 0 312 | 0.500985768967 0.046889654971 -0.864184752767 3.507043603209 313 | 0.020524128070 0.997606716375 0.066027288386 -0.050311176833 314 | 0.865212509633 -0.050815380559 0.498824398491 -1.773985217752 315 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 316 | 63 63 0 317 | 0.473062910712 0.051160880199 -0.879542248419 3.874379407120 318 | 0.018009960694 0.997542386012 0.067711386420 -0.008012930047 319 | 0.880844846572 -0.047872276658 0.470978899059 -1.427811718633 320 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 321 | 64 64 0 322 | 0.487134993218 0.049647125873 -0.871914152601 4.257065829800 323 | 0.017564006641 0.997623949999 0.066618003093 0.020380761923 324 | 0.873149833811 -0.047766259619 0.485105533794 -1.052596119026 325 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 326 | 65 65 0 327 | 0.405546499419 0.051998132596 -0.912594093417 4.695755227867 328 | 0.018619679317 0.997703586104 0.065121892207 0.051495389228 329 | 0.913884616718 -0.043402160188 0.403647008332 -0.677532186414 330 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 331 | 66 66 0 332 | 0.244472855609 0.059649592075 -0.967819903722 5.032105853474 333 | 0.019071482312 0.997617217579 0.066303597699 0.090257724312 334 | 0.969468781569 -0.034667198772 0.242752723663 -0.196390241749 335 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 336 | 67 67 0 337 | 0.089212397020 0.063651681340 -0.993977819095 5.109729152197 338 | 0.014977697289 0.997757317344 0.065238101732 0.097486059991 339 | 0.995901154721 -0.020707602379 0.088058964938 0.371751317474 340 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 341 | 68 68 0 342 | -0.032744688501 0.064944792642 -0.997350926414 5.037224508786 343 | 0.010036215158 0.997857643528 0.064648243432 0.134252741116 344 | 0.999412813053 -0.007892711972 -0.033326336795 0.857975006718 345 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 346 | 69 69 0 347 | -0.173869731655 0.058636611268 -0.983020747782 5.023832345429 348 | 0.006495072710 0.998272278522 0.058397517836 0.190009358429 349 | 0.984746595212 0.003768803249 -0.173950181345 1.489668021532 350 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 351 | 70 70 0 352 | -0.275995767116 0.052105510161 -0.959745601361 4.855437016106 353 | 0.002736290494 0.998568044149 0.053426343858 0.244449677743 354 | 0.961155094787 0.012119295134 -0.275743129351 2.174332101116 355 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 356 | 71 71 0 357 | -0.379418430009 0.044068859353 -0.924175880781 4.530032643087 358 | -0.002853068929 0.998804552944 0.048798834905 0.282828449360 359 | 0.925221585881 0.021151877595 -0.378839124815 2.651606823753 360 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 361 | 72 72 0 362 | -0.483290490500 0.029762958489 -0.874953584620 4.312469892136 363 | -0.006950864015 0.999259983160 0.037830823408 0.347039788848 364 | 0.875432061571 0.024364975112 -0.482725968816 3.180840132292 365 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 366 | 73 73 0 367 | -0.592386946580 0.017046469955 -0.805472790225 4.067993122822 368 | -0.013068521340 0.999441276958 0.030762760170 0.366496484498 369 | 0.805547150502 0.028749809136 -0.591833193940 3.723165275614 370 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 371 | 74 74 0 372 | -0.676838126657 0.004626843221 -0.736117427128 3.675347693919 373 | -0.019427997744 0.999519648464 0.024145916271 0.413792311566 374 | 0.735875551369 0.030644162425 -0.676423116157 4.043452263397 375 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 376 | 75 75 0 377 | -0.757690608517 -0.007128846000 -0.652576745909 3.357367887801 378 | -0.027300087138 0.999411281772 0.020779698625 0.457415189323 379 | 0.652044427158 0.033559949157 -0.757439160908 4.451152826969 380 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 381 | 76 76 0 382 | -0.816470897430 -0.015559964617 -0.577176862659 2.950564932194 383 | -0.031494228973 0.999348782402 0.017610356115 0.477608422997 384 | 0.576526978406 0.032556083951 -0.816429246295 4.897096581034 385 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 386 | 77 77 0 387 | -0.864989339543 -0.022796253560 -0.501271444110 2.371295626743 388 | -0.036150738860 0.999202748849 0.016940793002 0.501990278105 389 | 0.500485618111 0.032774947922 -0.865123827080 5.239963471935 390 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 391 | 78 78 0 392 | -0.920747819948 -0.034224256653 -0.388652671932 1.806861734260 393 | -0.045746756075 0.998744146122 0.020429490378 0.518040597889 394 | 0.387465396458 0.036590026306 -0.921157143672 5.392244521178 395 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 396 | 79 79 0 397 | -0.967571575982 -0.046023525539 -0.248366409006 1.184280263958 398 | -0.054634582936 0.998116932507 0.027886380813 0.532206455182 399 | 0.246615288198 0.040551485600 -0.968264049158 5.501928006210 400 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 401 | 80 80 0 402 | -0.994096486028 -0.065687219492 -0.086356563967 0.592841272812 403 | -0.068792273173 0.997068964697 0.033482875079 0.511200935250 404 | 0.083904052921 0.039225871147 -0.995701527310 5.541330503439 405 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 406 | 81 81 0 407 | -0.996848660162 -0.078947744886 -0.007638274740 0.036047864471 408 | -0.079186599923 0.996099655155 0.038922437644 0.503057571689 409 | 0.004535642868 0.039404661360 -0.999212209480 5.452000878043 410 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 411 | 82 82 0 412 | -0.993326642515 -0.089607542155 0.072634635966 -0.558568409296 413 | -0.086670959879 0.995324638104 0.042626480235 0.502090607496 414 | -0.076114694158 0.036046643291 -0.996448853887 5.391965498147 415 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 416 | 83 83 0 417 | -0.985109780213 -0.096039008702 0.142606753940 -1.220873402038 418 | -0.089946184540 0.994760702471 0.048588399343 0.478382716906 419 | -0.146525974996 0.035037943312 -0.988586840022 5.308028334125 420 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 421 | 84 84 0 422 | -0.956080301638 -0.113065592003 0.270418961372 -1.748691620086 423 | -0.099974865513 0.993072007549 0.061749601868 0.442166258844 424 | -0.275527256419 0.032002483814 -0.960760301757 5.070987076440 425 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 426 | 85 85 0 427 | -0.911983196849 -0.127002669578 0.390071249599 -2.259789442156 428 | -0.109577568406 0.991737358141 0.066706543602 0.375972103316 429 | -0.395320141589 0.018092218691 -0.918364449341 4.768677165151 430 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 431 | 86 86 0 432 | -0.871418542028 -0.129796039059 0.473059175406 -2.821787734460 433 | -0.116129580566 0.991531484256 0.058131286941 0.302017044483 434 | -0.476598274975 -0.004279514980 -0.879112080430 4.454490047145 435 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 436 | 87 87 0 437 | -0.810166605535 -0.129364827384 0.571749018171 -3.300027849300 438 | -0.121901665351 0.991203265747 0.051537173900 0.280350970876 439 | -0.573386590642 -0.027943474102 -0.818809573192 4.120325585335 440 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 441 | 88 88 0 442 | -0.750775189740 -0.124359140842 0.648744125682 -3.818804391902 443 | -0.124226749582 0.991176041109 0.046235892245 0.257556480415 444 | -0.648769490040 -0.045878613018 -0.759599112177 3.666853101236 445 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 446 | 89 89 0 447 | -0.659930295144 -0.121019012608 0.741516704221 -4.227736396667 448 | -0.125475001428 0.990834035699 0.050039395801 0.210185842353 449 | -0.740775706991 -0.060019294422 -0.669066258403 3.216428368432 450 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 451 | 90 90 0 452 | -0.531833510768 -0.121390210040 0.838104968066 -4.499388208628 453 | -0.127236940330 0.989892745253 0.062634892599 0.172737834040 454 | -0.837237291098 -0.073326568596 -0.541903452933 2.665017882539 455 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 456 | 91 91 0 457 | -0.408907143134 -0.119994072784 0.904652393246 -4.779613987092 458 | -0.127043324589 0.989149558621 0.073777646592 0.114110961572 459 | -0.903689395637 -0.084761842570 -0.419714766080 2.074354994819 460 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 461 | 92 92 0 462 | -0.318757842661 -0.116889740256 0.940602612406 -5.043874237096 463 | -0.126309688552 0.988754171833 0.080069196659 0.056556044508 464 | -0.939384026061 -0.093284523361 -0.329937453499 1.520661604652 465 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 466 | 93 93 0 467 | -0.212103812686 -0.116571714897 0.970268969208 -5.129005270942 468 | -0.124459954109 0.987997226291 0.091494204313 -0.000036081110 469 | -0.969288686174 -0.101353366425 -0.224066488887 0.970587300879 470 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 471 | 94 94 0 472 | -0.092917431371 -0.114149094716 0.989109096100 -5.164463124178 473 | -0.122404321523 0.987180692181 0.102427870019 -0.039381151536 474 | -0.988121450979 -0.111553891280 -0.105698636716 0.425466843036 475 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 476 | 95 95 0 477 | 0.020177307941 -0.113483419281 0.993334367969 -5.207143142750 478 | -0.118969143551 0.986205691745 0.115085443179 -0.072536861183 479 | -0.992692296698 -0.120498256823 0.006397950746 -0.072116137466 480 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 481 | 96 96 0 482 | 0.140140171602 -0.110075731845 0.983993600641 -5.100854469170 483 | -0.117265051262 0.984961495697 0.126884783219 -0.123011792829 484 | -0.983162743698 -0.133169717724 0.125124636700 -0.480481735340 485 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 486 | 97 97 0 487 | 0.216734443356 -0.099162851394 0.971181345056 -4.956378622347 488 | -0.114957730419 0.985313660371 0.126260510192 -0.173571676754 489 | -0.969438598519 -0.139009802246 0.202151871354 -1.020934444456 490 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 491 | 98 98 0 492 | 0.329049893841 -0.080955978411 0.940835667460 -4.812558673128 493 | -0.108005363418 0.986553807756 0.122663829137 -0.208646385875 494 | -0.938115379406 -0.141977825962 0.315881745954 -1.551330512962 495 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 496 | 99 99 0 497 | 0.444650210640 -0.065026386810 0.893340966272 -4.469705693711 498 | -0.101754360386 0.987237452872 0.122508241387 -0.225733574024 499 | -0.889905929379 -0.145374647322 0.432358622836 -2.020859859659 500 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 501 | 100 100 0 502 | 0.572942721020 -0.049722815741 0.818085757455 -4.109204960298 503 | -0.092638339423 0.987832694666 0.124918798316 -0.252654388730 504 | -0.814343172762 -0.147357421593 0.561365312895 -2.454759428427 505 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 506 | 101 101 0 507 | 0.652424556157 -0.034953390699 0.757047458642 -3.853526884125 508 | -0.086180810282 0.989034088123 0.119935203136 -0.290313309964 509 | -0.752937887277 -0.143491621674 0.642257813981 -2.866528654462 510 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 511 | 102 102 0 512 | 0.695799183059 -0.029118627416 0.717646007569 -3.542861066960 513 | -0.079006225252 0.990011386762 0.116771043859 -0.303327741705 514 | -0.713877932853 -0.137947692441 0.686548561062 -3.423998094609 515 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 516 | 103 103 0 517 | 0.762337648417 -0.026504296549 0.646636724645 -3.206247873574 518 | -0.070146321624 0.989890777874 0.123271046352 -0.298807172220 519 | -0.643366944253 -0.139333339766 0.752771828630 -3.974749271671 520 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 521 | 104 104 0 522 | 0.844331796419 -0.021826200602 0.535375886000 -2.729450223382 523 | -0.058636070141 0.989405541449 0.132809936932 -0.328376816428 524 | -0.532602603844 -0.143527993913 0.834106755683 -4.330627849986 525 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 526 | 105 105 0 527 | 0.905160822022 -0.014053074879 0.424836764753 -2.267952708658 528 | -0.051556738413 0.988444835623 0.142543659807 -0.333280032841 529 | -0.421930880979 -0.150928139568 0.893977009466 -4.513765602249 530 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 531 | 106 106 0 532 | 0.951128130486 -0.005053607344 0.308755156179 -1.745956988347 533 | -0.043052712762 0.987930400753 0.148795123165 -0.308063830281 534 | -0.305780557489 -0.154815974004 0.939430823591 -4.713533245663 535 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 536 | 107 107 0 537 | 0.984482225294 0.006031227580 0.175380639127 -1.190114536718 538 | -0.033565600897 0.987428679330 0.154460190993 -0.333096698967 539 | -0.172244287926 -0.157950069513 0.972308425372 -4.800397299186 540 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 541 | 108 108 0 542 | 0.999684879195 0.024977877543 0.002499486214 -0.768480709927 543 | -0.025051131230 0.986301987236 0.163036218659 -0.289566766312 544 | 0.001607053813 -0.163047457521 0.986616907559 -4.551461861346 545 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 546 | 109 109 0 547 | 0.994506107440 0.036014121014 -0.098288322080 -0.317458270527 548 | -0.019743036756 0.986634150703 0.161750693452 -0.292081050820 549 | 0.102799920571 -0.158921544858 0.981924716162 -4.198538013926 550 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 551 | 110 110 0 552 | 0.987969045327 0.029788056094 -0.151755848967 0.030452000434 553 | -0.014853259618 0.995015065736 0.098612371671 -0.292489328837 554 | 0.153936826848 -0.095171901746 0.983486534301 -3.808822527173 555 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 556 | 111 111 0 557 | 0.970119299130 0.012851087720 -0.242287926967 0.306618715528 558 | -0.003893205665 0.999292242443 0.037414678915 -0.253499105057 559 | 0.242597264946 -0.035353426893 0.969482721739 -3.346615135884 560 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 561 | 112 112 0 562 | 0.941244453180 -0.006815860090 -0.337657138054 0.629923218281 563 | 0.012256359655 0.999827110081 0.013983252785 -0.209268714266 564 | 0.337503452538 -0.017300108718 0.941165259199 -2.862467999333 565 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 566 | 113 113 0 567 | 0.866769504002 -0.034453256624 -0.497517450845 0.696795529636 568 | 0.027989908813 0.999399102554 -0.020445020952 -0.196916736100 569 | 0.497922891411 0.003795653453 0.867213007878 -2.392662524493 570 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 571 | 114 114 0 572 | 0.817628313261 -0.069099560057 -0.571585054251 0.872327324364 573 | 0.045282179724 0.997414359839 -0.055804327657 -0.185498525272 574 | 0.573963193631 0.019744609028 0.818643196570 -1.979058721596 575 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 576 | 115 115 0 577 | 0.741076392577 -0.145696240762 -0.655422100328 1.254601963565 578 | 0.061751703137 0.986824981950 -0.149543201526 -0.154082074759 579 | 0.668574791127 0.070349466173 0.740309694875 -1.629409352922 580 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 581 | 116 116 0 582 | 0.637921549564 -0.205474040548 -0.742183504206 1.494244879361 583 | 0.080271507255 0.976239614641 -0.201277642425 -0.113763365599 584 | 0.765906273886 0.068823127494 0.639258004246 -1.228164216089 585 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 586 | 117 117 0 587 | 0.514795930644 -0.249749442557 -0.820128767837 1.845979047713 588 | 0.096826879113 0.967443588113 -0.233832236869 -0.080253102685 589 | 0.851827761565 0.040965539913 0.522218447172 -0.812163785006 590 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 591 | 118 118 0 592 | 0.289774428466 -0.280388736339 -0.915102917742 2.121331459241 593 | 0.099384905860 0.959771649138 -0.262604351424 -0.052792458763 594 | 0.951921128042 -0.014851310830 0.305983672846 -0.339161220134 595 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 596 | 119 119 0 597 | 0.025350537839 -0.288583488331 -0.957118864040 2.180645769088 598 | 0.100619158394 0.953301270892 -0.284767365908 -0.005671144964 599 | 0.994601797003 -0.089085565527 0.053203742983 0.155874449702 600 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 601 | 120 120 0 602 | -0.220677203444 -0.269331374287 -0.937424406680 2.267857113578 603 | 0.102432523054 0.949402997867 -0.296886548482 0.051950866150 604 | 0.969954372966 -0.161538401853 -0.181923391783 0.616728094926 605 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 606 | 121 121 0 607 | -0.433364582410 -0.232606271724 -0.870682556084 2.196866944875 608 | 0.093997409745 0.949182037137 -0.300362946383 0.098799748709 609 | 0.896302559449 -0.212008808670 -0.389477445603 1.180985430776 610 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 611 | 122 122 0 612 | -0.604214929279 -0.182337509038 -0.775678561986 1.947778242177 613 | 0.086132292819 0.952816654610 -0.291069832321 0.147331194283 614 | 0.792152401284 -0.242679731233 -0.560000896428 1.565205014583 615 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 616 | 123 123 0 617 | -0.739961844345 -0.110106383827 -0.663577126381 1.678635216022 618 | 0.072869610731 0.967584191750 -0.241807527952 0.201553284032 619 | 0.668691287701 -0.227282742378 -0.707952002445 1.965476384124 620 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 621 | 124 124 0 622 | -0.883977643754 -0.068376052977 -0.462500151091 1.290087824719 623 | 0.040514124244 0.974323229466 -0.221478723659 0.207461993608 624 | 0.465768483388 -0.214520243045 -0.858509731608 2.265881086767 625 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 626 | 125 125 0 627 | -0.964953337345 -0.035718963653 -0.259982841735 0.818046808825 628 | 0.017760625489 0.979533079806 -0.200498192461 0.199969567389 629 | 0.261823380437 -0.198088668615 -0.944569342655 2.400695151078 630 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 631 | 126 126 0 632 | -0.998941091902 -0.015090263870 -0.043481887019 0.313035644907 633 | -0.006461067085 0.981346483576 -0.192138881045 0.174047778578 634 | 0.045570222454 -0.191654321458 -0.980404842818 2.488453132266 635 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 636 | 127 127 0 637 | -0.985720824871 0.003125517315 0.168348814650 -0.260911270161 638 | -0.029328592673 0.981356494078 -0.189945343734 0.151277683747 639 | -0.165803877833 -0.192170838308 -0.967251834383 2.465421132048 640 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 641 | 128 128 0 642 | -0.946896870644 0.023018358870 0.320717020418 -0.739492959809 643 | -0.038138930091 0.982352788688 -0.183107747456 0.137232515758 644 | -0.319272100319 -0.185615679085 -0.929308912462 2.188562293102 645 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 646 | 129 129 0 647 | -0.897090056893 0.051871829373 0.438790302825 -1.159748992855 648 | -0.043984179704 0.977668300372 -0.205499549973 0.098813042221 649 | -0.439651007586 -0.203651630047 -0.874774950001 1.979987228502 650 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 651 | 130 130 0 652 | -0.873610189311 0.133512268872 0.467948791106 -1.580883411128 653 | -0.038821507549 0.939438923886 -0.340510324630 0.068163657557 654 | -0.485071631400 -0.315640404081 -0.815520153329 1.839364294882 655 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 656 | 131 131 0 657 | -0.763390430192 0.183810387349 0.619233910731 -1.963458959122 658 | -0.056355875957 0.936048890803 -0.347327735910 0.028441498691 659 | -0.643475648290 -0.300043800786 -0.704212034407 1.487074012800 660 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 661 | 132 132 0 662 | -0.545142785975 0.249728617577 0.800283114658 -2.275549833284 663 | -0.061506120357 0.940115608491 -0.335260445497 -0.001553514108 664 | -0.836082796859 -0.231987471039 -0.497137337318 1.101329652675 665 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 666 | 133 133 0 667 | -0.352619356960 0.290022778381 0.889688936052 -2.472362808041 668 | -0.042273262208 0.944851480177 -0.324759376711 -0.057486217184 669 | -0.934811524435 -0.152126491709 -0.320912713235 0.660414521726 670 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 671 | 134 134 0 672 | -0.093958489101 0.299610126767 0.949424259809 -2.538780857430 673 | -0.034705305822 0.952077353400 -0.303882036592 -0.086805537634 674 | -0.994971454325 -0.061502214222 -0.079057712987 0.245525016483 675 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 676 | 135 135 0 677 | 0.186117317720 0.274741406036 0.943333380011 -2.461476353324 678 | -0.019774921940 0.960961643982 -0.275974072371 -0.105142553265 679 | -0.982328691679 0.032709264255 0.184284585194 -0.157499325013 680 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 681 | 136 136 0 682 | 0.334233204317 0.240177812605 0.911374733672 -2.278525727142 683 | -0.000018811351 0.966986749591 -0.254826767400 -0.134033688854 684 | -0.942491000748 0.085154565759 0.323203579397 -0.427307123221 685 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 686 | 137 137 0 687 | 0.535915234838 0.197894625312 0.820751799530 -2.022791325790 688 | 0.001242615861 0.971955073704 -0.235163448046 -0.148506827304 689 | -0.844271434471 0.127047662960 0.520639611670 -0.805616416849 690 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 691 | 138 138 0 692 | 0.722340639191 0.150546872382 0.674951827368 -1.754514848654 693 | 0.004931520212 0.974869775747 -0.222720969439 -0.182210176984 694 | -0.691520072131 0.164208980678 0.703445628302 -1.230542520712 695 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 696 | 139 139 0 697 | 0.820200373682 0.105245595137 0.562311896045 -1.323697995017 698 | 0.019522370604 0.977209821492 -0.211376054321 -0.172546284937 699 | -0.571743107327 0.184348376718 0.799453217486 -1.468717499438 700 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 701 | 140 140 0 702 | 0.916728281055 0.059859942198 0.395001231728 -0.935945490034 703 | 0.025531348363 0.977912359434 -0.207450110059 -0.168857957645 704 | -0.398694539713 0.200260293700 0.894951611385 -1.658916294560 705 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 706 | 141 141 0 707 | 0.964754765061 0.029138607869 0.261532485244 -0.514150854969 708 | 0.032827068415 0.972760971948 -0.229474439371 -0.144263084025 709 | -0.261095160594 0.229971903233 0.937519247876 -1.860983362711 710 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 711 | 142 142 0 712 | 0.990565868350 -0.007915748349 0.136808664283 -0.178095448116 713 | 0.045899395595 0.959830788182 -0.276799824538 -0.076889977608 714 | -0.129122094077 0.280467891760 0.951138945867 -1.898532517741 715 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 716 | 143 143 0 717 | 0.997928893906 -0.057826443627 -0.028178389693 -0.011519240609 718 | 0.047504977863 0.957855617822 -0.283294584658 -0.034476265018 719 | 0.043372759959 0.281369236122 0.958618843520 -1.978733690476 720 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 721 | 144 144 0 722 | 0.996383174704 -0.082533005125 -0.020220618319 0.020665495032 723 | 0.075443570913 0.968718147802 -0.236417909367 -0.045257046021 724 | 0.039100357390 0.234037311825 0.971441047097 -2.171363597270 725 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 726 | 145 145 0 727 | 0.985857587582 -0.094220508775 -0.138590549961 0.396277597348 728 | 0.063255020014 0.975023026439 -0.212905963900 -0.046621543949 729 | 0.155189069381 0.201128423519 0.967193762645 -2.072693074642 730 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 731 | 146 146 0 732 | 0.906419769834 -0.140911460227 -0.398179976329 0.800663853470 733 | 0.053646236105 0.973482146339 -0.222383968862 -0.040939520738 734 | 0.418957533080 0.180212398663 0.889942825388 -1.951683031169 735 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 736 | 147 147 0 737 | 0.845300713521 -0.181632882877 -0.502470325012 1.078876957883 738 | 0.076885851566 0.972006784602 -0.222016706043 -0.007007719436 739 | 0.528730079993 0.149038074971 0.835603013965 -1.735348793322 740 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 741 | 148 148 0 742 | 0.792087945275 -0.198949251193 -0.577075232422 1.280609472172 743 | 0.083054697943 0.971729105577 -0.221007815622 0.043909098103 744 | 0.604730142770 0.127128804234 0.786218583717 -1.580715131317 745 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 746 | 149 149 0 747 | 0.798945554392 -0.171231683413 -0.576511405694 1.327600170379 748 | 0.084972458376 0.981134216931 -0.173652816040 0.076204894976 749 | 0.595369945174 0.089751489106 0.798422812150 -1.506168796957 750 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 751 | 150 150 0 752 | 0.819170108398 -0.142970757974 -0.555445486017 1.340279033640 753 | 0.075458639278 0.986880280850 -0.142735084864 0.081028331258 754 | 0.568565140798 0.075011152887 0.819211205782 -1.472321729168 755 | 0.000000000000 0.000000000000 0.000000000000 1.000000000000 756 | --------------------------------------------------------------------------------