|
| 1 | +/* |
| 2 | + * Copyright (C) 2015, Nils Moehrle, Michael Waechter |
| 3 | + * TU Darmstadt - Graphics, Capture and Massively Parallel Computing |
| 4 | + * All rights reserved. |
| 5 | + * |
| 6 | + * This software may be modified and distributed under the terms |
| 7 | + * of the BSD 3-Clause license. See the LICENSE.txt file for details. |
| 8 | + */ |
| 9 | + |
| 10 | +#include "arguments.h" |
| 11 | +#include "util/file_system.h" |
| 12 | + |
| 13 | +#define SKIP_GLOBAL_SEAM_LEVELING "skip_global_seam_leveling" |
| 14 | +#define SKIP_GEOMETRIC_VISIBILITY_TEST "skip_geometric_visibility_test" |
| 15 | +#define SKIP_LOCAL_SEAM_LEVELING "skip_local_seam_leveling" |
| 16 | +#define NO_INTERMEDIATE_RESULTS "no_intermediate_results" |
| 17 | +#define WRITE_TIMINGS "write_timings" |
| 18 | +#define SKIP_HOLE_FILLING "skip_hole_filling" |
| 19 | +#define KEEP_UNSEEN_FACES "keep_unseen_faces" |
| 20 | + |
| 21 | +Arguments parse_args(int argc, char **argv) { |
| 22 | + util::Arguments args; |
| 23 | + args.set_exit_on_error(true); |
| 24 | + args.set_nonopt_maxnum(3); |
| 25 | + args.set_nonopt_minnum(3); |
| 26 | + args.set_helptext_indent(34); |
| 27 | + args.set_description("Textures a mesh given images in form of a 3D scene."); |
| 28 | + args.set_usage("Usage: " + std::string(argv[0]) + " [options] IN_SCENE IN_MESH OUT_PREFIX" |
| 29 | + "\n\nIN_SCENE := (SCENE_FOLDER | BUNDLE_FILE | MVE_SCENE::EMBEDDING)" |
| 30 | + "\n\nSCENE_FOLDER:" |
| 31 | + "\nWithin a scene folder a .cam file has to be given for each image." |
| 32 | + "\nA .cam file is structured as follows:" |
| 33 | + "\n tx ty tz R00 R01 R02 R10 R11 R12 R20 R21 R22" |
| 34 | + "\n f d0 d1 paspect ppx ppy" |
| 35 | + "\nFirst line: Extrinsics - translation vector and rotation matrix" |
| 36 | + "\nSecond line: Intrinsics - focal length, distortion coefficients, pixel aspect ratio and principal point" |
| 37 | + "\nThe focal length is the distance between camera center and image plane normalized by dividing with the larger image dimension." |
| 38 | + "\nFor non zero distortion coefficients the image will be undistorted prior to the texturing process." |
| 39 | + " If only d0 is non zero the Noah Snavely's distortion model is assumed otherwise the distortion model of VSFM is assumed." |
| 40 | + "\nThe pixel aspect ratio is usually 1 or close to 1. If your SfM system doesn't output it, but outputs a different focal length in x and y direction, you have to encode this here." |
| 41 | + "\nThe principal point has to be given in unit dimensions (e.g. 0.5 0.5)." |
| 42 | + "\n\nBUNDLE_FILE:" |
| 43 | + "\nCurrently only NVM bundle files (from VisualSFM, http://ccwu.me/vsfm/) are supported." |
| 44 | + "\nSince the bundle file contains relative paths to the images please make sure you did not move them (relative to the bundle) or rename them after the bundling process." |
| 45 | + "\n\nMVE_SCENE::EMBEDDING:" |
| 46 | + "\nThis is the scene representation we use in our research group: http://www.gris.tu-darmstadt.de/projects/multiview-environment/." |
| 47 | + "\n\nIN_MESH:" |
| 48 | + "\nThe mesh that you want to texture and which needs to be in the same coordinate frame as the camera parameters. You can reconstruct one, e.g. with CMVS: http://www.di.ens.fr/cmvs/" |
| 49 | + "\n\nOUT_PREFIX:" |
| 50 | + "\nA path and name for the output files, e.g. <path>/<to>/my_textured_mesh" |
| 51 | + "\nDon't append an obj extension. The application does that itself because it outputs multiple files (mesh, material file, texture files)." |
| 52 | + "\n"); |
| 53 | + args.add_option('D',"data_cost_file", true, |
| 54 | + "Skip calculation of data costs and use the ones provided in the given file"); |
| 55 | + args.add_option('L',"labeling_file", true, |
| 56 | + "Skip view selection and use the labeling provided in the given file"); |
| 57 | + args.add_option('d',"data_term", true, |
| 58 | + "Data term: {" + |
| 59 | + choices<tex::DataTerm>() + "} [" + |
| 60 | + choice_string<tex::DataTerm>(tex::DATA_TERM_GMI) + "]"); |
| 61 | + args.add_option('s',"smoothness_term", true, |
| 62 | + "Smoothness term: {" + |
| 63 | + choices<tex::SmoothnessTerm>() + "} [" + |
| 64 | + choice_string<tex::SmoothnessTerm>(tex::SMOOTHNESS_TERM_POTTS) + "]"); |
| 65 | + args.add_option('o',"outlier_removal", true, |
| 66 | + "Photometric outlier (pedestrians etc.) removal method: {" + |
| 67 | + choices<tex::OutlierRemoval>() + "} [" + |
| 68 | + choice_string<tex::OutlierRemoval>(tex::OUTLIER_REMOVAL_NONE) + "]"); |
| 69 | + args.add_option('t',"tone_mapping", true, |
| 70 | + "Tone mapping method: {" + |
| 71 | + choices<tex::ToneMapping>() + "} [" + |
| 72 | + choice_string<tex::ToneMapping>(tex::TONE_MAPPING_NONE) + "]"); |
| 73 | + args.add_option('v',"view_selection_model", false, |
| 74 | + "Write out view selection model [false]"); |
| 75 | + args.add_option('\0', SKIP_GEOMETRIC_VISIBILITY_TEST, false, |
| 76 | + "Skip geometric visibility test based on ray intersection [false]"); |
| 77 | + args.add_option('\0', SKIP_GLOBAL_SEAM_LEVELING, false, |
| 78 | + "Skip global seam leveling [false]"); |
| 79 | + args.add_option('\0', SKIP_LOCAL_SEAM_LEVELING, false, |
| 80 | + "Skip local seam leveling (Poisson editing) [false]"); |
| 81 | + args.add_option('\0', SKIP_HOLE_FILLING, false, |
| 82 | + "Skip hole filling [false]"); |
| 83 | + args.add_option('\0', KEEP_UNSEEN_FACES, false, |
| 84 | + "Keep unseen faces [false]"); |
| 85 | + args.add_option('\0', WRITE_TIMINGS, false, |
| 86 | + "Write out timings for each algorithm step (OUT_PREFIX + _timings.csv)"); |
| 87 | + args.add_option('\0', NO_INTERMEDIATE_RESULTS, false, |
| 88 | + "Do not write out intermediate results"); |
| 89 | + args.parse(argc, argv); |
| 90 | + |
| 91 | + Arguments conf; |
| 92 | + conf.in_scene = args.get_nth_nonopt(0); |
| 93 | + conf.in_mesh = args.get_nth_nonopt(1); |
| 94 | + conf.out_prefix = util::fs::sanitize_path(args.get_nth_nonopt(2)); |
| 95 | + |
| 96 | + /* Set defaults for optional arguments. */ |
| 97 | + conf.data_cost_file = ""; |
| 98 | + conf.labeling_file = ""; |
| 99 | + |
| 100 | + conf.write_timings = false; |
| 101 | + conf.write_intermediate_results = true; |
| 102 | + conf.write_view_selection_model = false; |
| 103 | + |
| 104 | + /* Handle optional arguments. */ |
| 105 | + for (util::ArgResult const* i = args.next_option(); |
| 106 | + i != 0; i = args.next_option()) { |
| 107 | + switch (i->opt->sopt) { |
| 108 | + case 'v': |
| 109 | + conf.write_view_selection_model = true; |
| 110 | + break; |
| 111 | + case 'D': |
| 112 | + conf.data_cost_file = i->arg; |
| 113 | + break; |
| 114 | + case 'L': |
| 115 | + conf.labeling_file = i->arg; |
| 116 | + break; |
| 117 | + case 'd': |
| 118 | + conf.settings.data_term = parse_choice<tex::DataTerm>(i->arg); |
| 119 | + break; |
| 120 | + case 's': |
| 121 | + conf.settings.smoothness_term = parse_choice<tex::SmoothnessTerm>(i->arg); |
| 122 | + break; |
| 123 | + case 'o': |
| 124 | + conf.settings.outlier_removal = parse_choice<tex::OutlierRemoval>(i->arg); |
| 125 | + break; |
| 126 | + case 't': |
| 127 | + conf.settings.tone_mapping = parse_choice<tex::ToneMapping>(i->arg); |
| 128 | + break; |
| 129 | + case '\0': |
| 130 | + if (i->opt->lopt == SKIP_GEOMETRIC_VISIBILITY_TEST) { |
| 131 | + conf.settings.geometric_visibility_test = false; |
| 132 | + } else if (i->opt->lopt == SKIP_GLOBAL_SEAM_LEVELING) { |
| 133 | + conf.settings.global_seam_leveling = false; |
| 134 | + } else if (i->opt->lopt == SKIP_LOCAL_SEAM_LEVELING) { |
| 135 | + conf.settings.local_seam_leveling = false; |
| 136 | + } else if (i->opt->lopt == SKIP_HOLE_FILLING) { |
| 137 | + conf.settings.hole_filling = false; |
| 138 | + } else if (i->opt->lopt == KEEP_UNSEEN_FACES) { |
| 139 | + conf.settings.keep_unseen_faces = true; |
| 140 | + } else if (i->opt->lopt == WRITE_TIMINGS) { |
| 141 | + conf.write_timings = true; |
| 142 | + } else if (i->opt->lopt == NO_INTERMEDIATE_RESULTS) { |
| 143 | + conf.write_intermediate_results = false; |
| 144 | + } else { |
| 145 | + throw std::invalid_argument("Invalid long option"); |
| 146 | + } |
| 147 | + break; |
| 148 | + default: |
| 149 | + throw std::invalid_argument("Invalid short option"); |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + return conf; |
| 154 | +} |
| 155 | + |
| 156 | +std::string |
| 157 | +bool_to_string(bool b){ |
| 158 | + return b ? "True" : "False"; |
| 159 | +} |
| 160 | + |
| 161 | +std::string |
| 162 | +Arguments::to_string(){ |
| 163 | + std::stringstream out; |
| 164 | + out << "Input scene: \t" << in_scene << std::endl |
| 165 | + << "Input mesh: \t" << in_mesh << std::endl |
| 166 | + << "Output prefix: \t" << out_prefix << std::endl |
| 167 | + << "Datacost file: \t" << data_cost_file << std::endl |
| 168 | + << "Labeling file: \t" << labeling_file << std::endl |
| 169 | + << "Data term: \t" << choice_string<tex::DataTerm>(settings.data_term) << std::endl |
| 170 | + << "Smoothness term: \t" << choice_string<tex::SmoothnessTerm>(settings.smoothness_term) << std::endl |
| 171 | + << "Outlier removal method: \t" << choice_string<tex::OutlierRemoval>(settings.outlier_removal) << std::endl |
| 172 | + << "Tone mapping: \t" << choice_string<tex::ToneMapping>(settings.tone_mapping) << std::endl |
| 173 | + << "Apply global seam leveling: \t" << bool_to_string(settings.global_seam_leveling) << std::endl |
| 174 | + << "Apply local seam leveling: \t" << bool_to_string(settings.local_seam_leveling) << std::endl; |
| 175 | + |
| 176 | + return out.str(); |
| 177 | +} |
0 commit comments