CPPxDIC
C++ Digital Image Correlation library for fingertip 3D reconstruction
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1
8#include <iostream>
9#include <sstream>
10#include <string>
11#include <vector>
12#include <chrono>
13#include <getopt.h>
14#include "config.h"
15#include "dic_analysis.h"
16#include "logging.h"
17#include "stage_plan.h"
18#include "trial_selection.h"
19#include "utils.h"
20#include "xdic/xdic_mode.h"
21
22// Mode-specific dispatch headers (stubs for non-default modes).
23#if defined(XDIC_MODE_MIRRORED)
25#endif
26
27// Long-option ids for trial-level selection flags (no short equivalents).
28enum {
29 OPT_TRIAL = 1000,
39};
40
41// Print usage information
42void print_usage(const char* prog_name) {
43 std::cout << "Usage: " << prog_name << " [OPTIONS]\n\n"
44 << "FINGERTIP 3D RECONSTRUCTION using DIC\n\n"
45 << "OPTIONS:\n"
46 << " -s, --subject <id> Override subject ID (e.g., S09)\n"
47 << " -r, --reftrial <num> Override reference trial number\n"
48 << " -C, --config <file> Unified config file (default: config/default.cfg)\n"
49 << " -d, --dic-params <file> DIC parameters file (default: dic_params.txt)\n"
50 << " -n, --ncorr-params <file> NCorr parameters file (default: ncorr_params.txt)\n"
51 << " -v, --viz-params <file> Visualization parameters file (default: "
52 "visualization_params.txt)\n"
53 << " -h, --help Show this help message\n\n"
54 << "LOGGING:\n"
55 << " -V, --verbose Increase console verbosity (repeatable: -VV)\n"
56 << " -q, --quiet Quiet: only warnings and errors on the console\n"
57 << " --log-level <lvl> Console level: trace|debug|info|warn|error|off\n"
58 << " --log-file <path> Also write a full-detail (debug) log to <path>\n"
59 << " --debug Debug mode: debug-level console + source locations\n"
60 << " Env: CPPXDIC_LOG_LEVEL, CPPXDIC_LOG_FILE, CPPXDIC_LOG_CONSOLE also apply.\n\n"
61 << "TRIAL-LEVEL RUN MODES (mutually exclusive; pick at most one):\n"
62 << " (a) --trial <id> Run a single trial.\n"
63 << " (b) --trials <list> Trial list (e.g. 7,12,25); with SLURM_ARRAY_TASK_ID\n"
64 << " --trials-file <path> set, the Nth (1-based) trial is run for this task.\n"
65 << " (c) --subject-trial-csv <p> subject_trial.csv (header subject,trial). With\n"
66 << " SLURM_ARRAY_TASK_ID set, the Nth data line selects\n"
67 << " both subject and trial for this task.\n"
68 << " Without SLURM_ARRAY_TASK_ID, --trials/--trials-file run the whole list and\n"
69 << " --subject-trial-csv runs every row (grouped per subject).\n\n"
70 << "STAGE DECOMPOSITION (run sub-steps in separate processes; needs explicit trials):\n"
71 << " --stages <list> Comma list of stages to run. Tokens:\n"
72 << " all | d(=match,track,format) | match | track |\n"
73 << " format | e(=recon) | f(=deform). Default: all.\n"
74 << " --pair <p> Restrict Step-D work to stereopair p (1..num_pair).\n"
75 << " --cam <id> Restrict tracking to camera id (use with --stages track).\n"
76 << " Each sub-step checkpoints to / loads from disk, so e.g. a 'match' job, then\n"
77 << " per-camera 'track' jobs, then a 'format,e,f' job can run as separate SLURM tasks.\n\n"
78 << "EXAMPLES:\n"
79 << " " << prog_name << " --subject S10 --reftrial 3\n"
80 << " " << prog_name << " -s S08 -r 5 -d custom_dic.txt\n"
81 << " " << prog_name << " --subject S09 --trial 7\n"
82 << " SLURM_ARRAY_TASK_ID=$SLURM_ARRAY_TASK_ID " << prog_name
83 << " --subject S09 --trials 7,12,25\n"
84 << " SLURM_ARRAY_TASK_ID=$SLURM_ARRAY_TASK_ID " << prog_name
85 << " --subject-trial-csv subject_trial.csv\n"
86 << " " << prog_name << " --subject S09 --trial 7 --pair 1 --stages match\n"
87 << " " << prog_name << " --subject S09 --trial 7 --pair 1 --cam 1 --stages track\n"
88 << " " << prog_name << " --subject S09 --trial 7 --stages format,e,f\n"
89 << std::endl;
90}
91
92int main(int argc, char* argv[]) {
93 // Command-line argument parsing
94 std::string subject_override = "";
95 int reftrial_override = -1;
96 std::string config_file = "config/default.cfg";
97 std::string dic_params_file = "dic_params.txt";
98 std::string ncorr_params_file = "ncorr_params.txt";
99 std::string viz_params_file = "visualization_params.txt";
100
101 // Trial-level run-mode selectors (empty/unset => default run()).
102 int single_trial = -1;
103 std::string trials_spec; // --trials <list>
104 std::string trials_file; // --trials-file <path>
105 std::string subject_trial_csv; // --subject-trial-csv <path>
106
107 // Logging selectors (CLI overrides config-file values, which override env).
108 std::string cli_log_level;
109 std::string cli_log_file;
110 int verbose_count = 0;
111 bool quiet = false;
112 bool cli_debug = false;
113
114 // Stage decomposition selectors (empty => full pipeline, as before).
115 std::string stages_spec; // --stages e.g. "match" | "track" | "format,e,f" | "d"
116 int only_pair = 0; // --pair (0 = all stereopairs)
117 int only_cam = 0; // --cam (0 = both cameras within a pair)
118
119 static struct option long_options[] = {{"subject", required_argument, 0, 's'},
120 {"reftrial", required_argument, 0, 'r'},
121 {"config", required_argument, 0, 'C'},
122 {"dic-params", required_argument, 0, 'd'},
123 {"ncorr-params", required_argument, 0, 'n'},
124 {"viz-params", required_argument, 0, 'v'},
125 {"trial", required_argument, 0, OPT_TRIAL},
126 {"trials", required_argument, 0, OPT_TRIALS},
127 {"trials-file", required_argument, 0, OPT_TRIALS_FILE},
128 {"subject-trial-csv", required_argument, 0, OPT_SUBJECT_TRIAL_CSV},
129 {"verbose", no_argument, 0, 'V'},
130 {"quiet", no_argument, 0, 'q'},
131 {"log-level", required_argument, 0, OPT_LOG_LEVEL},
132 {"log-file", required_argument, 0, OPT_LOG_FILE},
133 {"debug", no_argument, 0, OPT_DEBUG},
134 {"stages", required_argument, 0, OPT_STAGES},
135 {"pair", required_argument, 0, OPT_PAIR},
136 {"cam", required_argument, 0, OPT_CAM},
137 {"help", no_argument, 0, 'h'},
138 {0, 0, 0, 0}};
139
140 int opt;
141 int option_index = 0;
142 while ((opt = getopt_long(argc, argv, "s:r:C:d:n:v:hVq", long_options, &option_index)) != -1) {
143 switch (opt) {
144 case 's':
145 subject_override = optarg;
146 break;
147 case 'C':
148 config_file = optarg;
149 break;
150 case 'r':
151 reftrial_override = std::stoi(optarg);
152 break;
153 case 'd':
154 dic_params_file = optarg;
155 break;
156 case 'n':
157 ncorr_params_file = optarg;
158 break;
159 case 'v':
160 viz_params_file = optarg;
161 break;
162 case OPT_STAGES:
163 stages_spec = optarg;
164 break;
165 case OPT_PAIR:
166 only_pair = std::stoi(optarg);
167 break;
168 case OPT_CAM:
169 only_cam = std::stoi(optarg);
170 break;
171 case OPT_TRIAL:
172 single_trial = std::stoi(optarg);
173 break;
174 case OPT_TRIALS:
175 trials_spec = optarg;
176 break;
177 case OPT_TRIALS_FILE:
178 trials_file = optarg;
179 break;
181 subject_trial_csv = optarg;
182 break;
183 case 'V':
184 ++verbose_count;
185 break;
186 case 'q':
187 quiet = true;
188 break;
189 case OPT_LOG_LEVEL:
190 cli_log_level = optarg;
191 break;
192 case OPT_LOG_FILE:
193 cli_log_file = optarg;
194 break;
195 case OPT_DEBUG:
196 cli_debug = true;
197 break;
198 case 'h':
199 print_usage(argv[0]);
200 return 0;
201 default:
202 print_usage(argv[0]);
203 return 1;
204 }
205 }
206
207 // Configure logging as early as possible from CLI + environment so that all
208 // subsequent output (including config loading) is leveled and, if requested,
209 // captured to the log file. Config-file values are merged in after load.
210 {
211 cppxdic::log::Options logopts;
212 if (!cli_log_level.empty()) {
213 logopts.console_level = cppxdic::log::levelFromString(cli_log_level);
214 logopts.console_level_set = true;
215 }
216 logopts.log_file = cli_log_file;
217 logopts.debug = cli_debug;
218 logopts.verbose = verbose_count;
219 logopts.quiet = quiet;
221 }
222
223 LOG_INFO << "FINGERTIP 3D RECONSTRUCTION using DIC";
224 LOG_INFO << "--------------------------------------";
225 LOG_INFO << "DIC analysis for the fingertip";
226
227 // ---- Resolve trial-level run mode (Part 2) --------------------------------
228 // Exactly one of the four selectors may be used. They produce either an
229 // explicit list of trials to run (selected_trials), and possibly a
230 // CSV-driven subject override. If none is used, selected_trials stays empty
231 // and the default DicAnalysis::run() path is taken (unchanged behaviour).
232 std::vector<int> selected_trials;
233 {
234 int mode_count = (single_trial >= 0 ? 1 : 0) + (!trials_spec.empty() ? 1 : 0) +
235 (!trials_file.empty() ? 1 : 0) + (!subject_trial_csv.empty() ? 1 : 0);
236 if (mode_count > 1) {
237 LOG_ERROR << "--trial, --trials, --trials-file and --subject-trial-csv "
238 "are mutually exclusive.";
239 return 1;
240 }
241
242 const int task_id = cppxdic::slurmArrayTaskId();
243 try {
244 if (single_trial >= 0) {
245 // (a) single trial
246 selected_trials = {single_trial};
247 } else if (!trials_spec.empty() || !trials_file.empty()) {
248 // (b) SLURM array over a list of trials
249 std::vector<int> trials = trials_file.empty()
250 ? cppxdic::parseTrialList(trials_spec)
251 : cppxdic::readTrialsFile(trials_file);
252 if (trials.empty()) {
253 LOG_ERROR << "trial list is empty.";
254 return 1;
255 }
256 if (task_id >= 0) {
257 if (task_id < 1 || static_cast<size_t>(task_id) > trials.size()) {
258 LOG_ERROR << "SLURM_ARRAY_TASK_ID=" << task_id
259 << " out of range 1.." << trials.size();
260 return 1;
261 }
262 selected_trials = {trials[task_id - 1]};
263 LOG_INFO << "[SLURM array] task " << task_id << " -> trial "
264 << selected_trials.front();
265 } else {
266 selected_trials = trials; // no array: run the whole list
267 }
268 } else if (!subject_trial_csv.empty()) {
269 // (c) SLURM array over (subject, trial) pairs from CSV
270 std::vector<cppxdic::SubjectTrial> rows =
271 cppxdic::readSubjectTrialCsv(subject_trial_csv);
272 if (rows.empty()) {
273 LOG_ERROR << "subject_trial CSV has no data rows: " << subject_trial_csv;
274 return 1;
275 }
276 if (task_id >= 0) {
277 if (task_id < 1 || static_cast<size_t>(task_id) > rows.size()) {
278 LOG_ERROR << "SLURM_ARRAY_TASK_ID=" << task_id
279 << " out of range 1.." << rows.size();
280 return 1;
281 }
282 const auto& row = rows[task_id - 1];
283 subject_override = row.subject; // CSV drives the subject
284 selected_trials = {row.trial};
285 LOG_INFO << "[SLURM array] task " << task_id << " -> subject "
286 << row.subject << ", trial " << row.trial;
287 } else {
288 // No array: process every row. Require all rows share one
289 // subject so a single Config run is well defined; otherwise
290 // ask the user to drive it via a SLURM array (or per-subject).
291 const std::string& subj0 = rows.front().subject;
292 for (const auto& row : rows) {
293 if (row.subject != subj0) {
294 LOG_ERROR << "subject_trial CSV spans multiple subjects ("
295 << subj0 << ", " << row.subject
296 << "). Use SLURM_ARRAY_TASK_ID to select a row, "
297 "or split the CSV per subject.";
298 return 1;
299 }
300 selected_trials.push_back(row.trial);
301 }
302 subject_override = subj0;
303 }
304 }
305 } catch (const std::exception& e) {
306 LOG_ERROR << "Error resolving trial selection: " << e.what();
307 return 1;
308 }
309 }
310
311 try {
312 // Three-tier override chain (lowest -> highest priority):
313 // 1. Compiled defaults (Config member initializers)
314 // 2. Config file(s) (unified config/default.cfg, then specific param files)
315 // 3. CLI arguments (override everything)
316 //
317 // Tier 1: compiled defaults (from class initialization)
318 Config config;
319
320 LOG_INFO << "Loading configuration files...";
321 LOG_INFO << "------------------------------";
322
323 // Tier 2a: unified config file (broadest config-file source)
324 config.loadFromConfigFile(config_file);
325
326 // Tier 2b: specific param files override the unified file where present
327 config.loadFromDicParamsFile(dic_params_file);
328 config.loadFromNcorrParamsFile(ncorr_params_file);
329 config.loadFromVisualizationParamsFile(viz_params_file);
330
331 // Tier 3: command-line overrides (highest priority)
332 if (!subject_override.empty()) {
333 config.overrideSubject(subject_override);
334 }
335 if (reftrial_override >= 0) {
336 config.overrideRefTrial(reftrial_override);
337 }
338
339 // Update derived variables
340 config.updateVariables();
341
342 // Register the stereopair -> cameras table so every Utils::getCamerasForPair
343 // caller (Step D import/tracking, Step E DLT lookup, checkpoints) honours
344 // dic_params.txt `camera_pairs` instead of the legacy {1,2 ; 4,3} table.
346
347 // Re-apply logging configuration now that config files are loaded, merging
348 // their values (log_level/log_file/debug_mode) under any CLI flags, which
349 // keep priority. Env was already applied in the early configure above.
350 {
351 cppxdic::log::Options logopts;
352 if (!config.log_level.empty()) {
354 logopts.console_level_set = true;
355 }
356 logopts.log_file = config.log_file;
357 logopts.debug = config.debug_mode;
358 // CLI flags override config-file values.
359 if (!cli_log_level.empty()) {
360 logopts.console_level = cppxdic::log::levelFromString(cli_log_level);
361 logopts.console_level_set = true;
362 }
363 if (!cli_log_file.empty()) logopts.log_file = cli_log_file;
364 if (cli_debug) logopts.debug = true;
365 logopts.verbose = verbose_count;
366 logopts.quiet = quiet;
368 }
369
370 // Announce the compile-time reconstruction mode (Section 2c).
371 LOG_INFO << "xDIC reconstruction mode: " << xdic::active_mode_name();
372
373 // Print final parameters
374 LOG_INFO << "Final Configuration:";
375 LOG_INFO << "--------------------";
376 LOG_INFO << "Subject: " << config.subject_id << ", Phase: " << config.phase_id
377 << ", Material: " << config.material << ", Stereo Pairs: " << config.num_pair;
378 LOG_INFO << "Reference trial number: " << config.ref_trial_id;
379 LOG_INFO << "Frame: " << config.idx_frame_start << " to " << config.idx_frame_end
380 << ", jump= " << config.frame_jump
381 << (config.force_frame_window ? " (forced, protocol window ignored)"
382 : " (protocol window applies when a .mat protocol exists)");
383 {
384 std::ostringstream pairs;
385 for (int p = 1; p <= config.num_pair; ++p) {
386 int c1 = 0, c2 = 0;
387 Utils::getCamerasForPair(p, c1, c2);
388 pairs << (p > 1 ? " " : "") << "pair" << p << "=(" << c1 << "," << c2 << ")";
389 }
390 LOG_INFO << "Camera pairs: " << pairs.str();
391 if (static_cast<int>(config.camera_pairs.size()) < config.num_pair) {
392 LOG_WARN << "camera_pairs lists " << config.camera_pairs.size() << " pair(s) but num_pair="
393 << config.num_pair << "; missing pairs default to (2N-1, 2N)";
394 }
395 }
396 LOG_INFO << "Saturation: " << (config.im_saturation_mode ? "on" : "off")
397 << " (limit_grayscale=" << (config.limit_grayscale > 0 ? std::to_string(config.limit_grayscale)
398 : std::string("auto"))
399 << "), Image filtering: " << (config.im_filter_mode ? "on" : "off")
400 << ", DIC engine: " << config.dic_engine
401 << ", Threads (step D): " << config.step_d.total_threads
402 << (config.parallel_processing ? " (parallel)" : " (sequential)");
403 LOG_INFO << "Show visualization: " << config.showvisu
404 << ", Debug mode: " << config.debug_mode
405 << ", Automatic process: " << config.automatic_process;
406
407#if defined(XDIC_MODE_CAMERAPAIRS)
408 // ---- Camera-pairs mode: the only fully-implemented reconstruction path. ----
409 // Checking
410 LOG_INFO << "Checking the data and protocol...";
411 if (!Utils::dicCheck(config)) {
412 LOG_ERROR << "Data and protocol check failed!";
413 return 1;
414 }
415 // Build the stage plan (default = full pipeline; unchanged behaviour).
416 StagePlan plan;
417 if (!stages_spec.empty()) {
418 std::string perr;
419 if (!StagePlan::parse(stages_spec, plan, &perr)) {
420 LOG_ERROR << "Invalid --stages '" << stages_spec << "': " << perr
421 << " (valid tokens: all, d, match, track, format, e, f)";
422 return 1;
423 }
424 }
425 plan.only_pair = only_pair;
426 plan.only_cam = only_cam;
427 const bool custom_plan = !stages_spec.empty() || only_pair != 0 || only_cam != 0;
428
429 // Stage decomposition is meant for explicit (array-driven) trial selection.
430 if (custom_plan && selected_trials.empty()) {
431 LOG_ERROR << "--stages/--pair/--cam require an explicit trial selection "
432 "(--trial / --trials / --trials-file / --subject-trial-csv).";
433 return 1;
434 }
435
436 // Call analysis function. If a trial-level run mode was selected, run
437 // the resolved trial list; otherwise use the default run() behaviour.
438 DicAnalysis dicAnalysis(config);
439 bool success;
440 if (!selected_trials.empty()) {
441 std::ostringstream trial_list;
442 for (size_t i = 0; i < selected_trials.size(); ++i) {
443 trial_list << selected_trials[i];
444 if (i + 1 < selected_trials.size()) trial_list << ", ";
445 }
446 LOG_INFO << "Running selected trials: [" << trial_list.str() << "]";
447 if (custom_plan) {
448 LOG_INFO << "Stage selection: stages='" << (stages_spec.empty() ? "all" : stages_spec)
449 << "' pair=" << only_pair << " cam=" << only_cam;
450 }
451 success = dicAnalysis.run(selected_trials, plan);
452 } else {
453 success = dicAnalysis.run();
454 }
455
456 if (success) {
457 LOG_INFO << "Analysis completed successfully!";
458 } else {
459 LOG_ERROR << "Analysis failed!";
460 return 1;
461 }
462#elif defined(XDIC_MODE_MIRRORED)
463 // ---- Mirrored-camera (MNG) mode (Section 2d). ----
464 if (!xdic::mirrored::run(config, selected_trials)) {
465 LOG_ERROR << "Mirrored mode failed.";
466 return 1;
467 }
468#elif defined(XDIC_MODE_MULTI)
469// ---- Multi-camera mode: STUB (Section 2e). ----
470// The multi-mode placeholder intentionally fails to compile (see
471// src/xdic/multi/multi_mode.cpp), so this branch is only reachable when that
472// translation unit is added to the build under XDIC_MODE=multi.
473#error "xdic multi-camera mode is not implemented"
474#endif
475
476 } catch (const std::exception& e) {
477 LOG_ERROR << e.what();
478 return 1;
479 }
480
481 LOG_INFO << "End of script";
482 return 0;
483}
std::string dic_engine
Definition config.h:211
int ref_trial_id
Definition config.h:75
void overrideSubject(const std::string &subject)
Definition config.cpp:622
bool showvisu
Definition config.h:83
bool im_filter_mode
Definition config.h:51
std::string subject_id
Definition config.h:65
void updateVariables()
Definition config.cpp:18
std::string material
Definition config.h:258
bool loadFromDicParamsFile(const std::string &filepath="dic_params.txt")
Definition config.cpp:124
bool loadFromConfigFile(const std::string &filepath="config/default.cfg")
Load a single unified config file (the middle tier of the override chain).
Definition config.cpp:607
std::vector< std::pair< int, int > > camera_pairs
Definition config.h:37
int idx_frame_start
Definition config.h:78
bool parallel_processing
Definition config.h:62
int num_pair
Definition config.h:34
void overrideRefTrial(int trial)
Definition config.cpp:628
bool debug_mode
Definition config.h:84
bool loadFromNcorrParamsFile(const std::string &filepath="ncorr_params.txt")
Definition config.cpp:345
std::string phase_id
Definition config.h:66
int limit_grayscale
Definition config.h:135
int frame_jump
Definition config.h:80
bool automatic_process
Definition config.h:61
bool im_saturation_mode
Definition config.h:56
StepConfig step_d
Definition config.h:138
bool loadFromVisualizationParamsFile(const std::string &filepath="visualization_params.txt")
Definition config.cpp:426
std::string log_level
Definition config.h:87
int idx_frame_end
Definition config.h:79
bool force_frame_window
Definition config.h:60
std::string log_file
Definition config.h:88
DIC Analysis class for CPPXDIC Main analysis functionality equivalent to Matlab dic_analysis....
bool run()
Run complete DIC analysis pipeline Executes preprocessing, Step D, Step E, and Step F in sequence.
static void setCameraPairs(const std::vector< std::pair< int, int > > &camera_pairs)
Register the process-wide stereopair -> (cam_first, cam_second) table.
Definition utils.cpp:246
static bool dicCheck(const Config &config)
Utility functions implementation for CPPXDIC.
Definition utils.cpp:23
static void getCamerasForPair(int stereopair, int &cam_first, int &cam_second)
Get camera numbers for a given stereopair using the registered table (setCameraPairs).
Definition utils.cpp:254
Lightweight, dependency-free logging facility for CPPxDIC.
#define LOG_ERROR
Definition logging.h:172
#define LOG_WARN
Definition logging.h:171
#define LOG_INFO
Definition logging.h:170
@ OPT_PAIR
Definition main.cpp:37
@ OPT_LOG_FILE
Definition main.cpp:34
@ OPT_TRIALS
Definition main.cpp:30
@ OPT_LOG_LEVEL
Definition main.cpp:33
@ OPT_SUBJECT_TRIAL_CSV
Definition main.cpp:32
@ OPT_TRIAL
Definition main.cpp:29
@ OPT_TRIALS_FILE
Definition main.cpp:31
@ OPT_STAGES
Definition main.cpp:36
@ OPT_DEBUG
Definition main.cpp:35
@ OPT_CAM
Definition main.cpp:38
int main(int argc, char *argv[])
Definition main.cpp:92
void print_usage(const char *prog_name)
Definition main.cpp:42
Interface for the mirrored-camera xDIC mode ("MNG" variant).
void configureFromOptions(const Options &opts)
Apply env vars, then the supplied options (CLI/config), to the singleton.
Definition logging.cpp:233
Level levelFromString(const std::string &s, Level fallback=Level::Info)
Parse a level name (case-insensitive): trace, debug, info, warn|warning, error, off.
Definition logging.cpp:96
std::vector< int > parseTrialList(const std::string &spec)
Parse a comma/space-separated list of integer trial IDs.
int slurmArrayTaskId()
Resolve SLURM_ARRAY_TASK_ID from the environment.
std::vector< int > readTrialsFile(const std::string &path)
Read a trials file: one trial ID per line.
std::vector< SubjectTrial > readSubjectTrialCsv(const std::string &path)
Read subject_trial.csv (header "subject,trial") into rows, skipping the header line and any blank/com...
bool run(const Config &config, const std::vector< int > &trials={})
Run the mirrored-camera 2D DIC pipeline.
constexpr const char * active_mode_name()
Human-readable name of the active mode.
Definition xdic_mode.h:55
StagePlan — selects which pipeline sub-steps a single process executes.
Definition stage_plan.h:21
int only_pair
0 = all stereopairs; otherwise restrict to this pair
Definition stage_plan.h:31
static bool parse(const std::string &spec, StagePlan &out, std::string *err)
Parse a comma-separated stage spec into out (stage booleans only; only_pair/only_cam are left untouch...
Definition stage_plan.h:54
int only_cam
0 = both cameras; otherwise restrict tracking to this camera id
Definition stage_plan.h:32
int total_threads
Definition config.h:22
Aggregated options resolved from env/config/CLI, applied in one call.
Definition logging.h:98
bool console_level_set
true if an explicit level was chosen
Definition logging.h:100
std::string log_file
empty = no file sink
Definition logging.h:101
int verbose
-V count: lowers threshold per step
Definition logging.h:104
bool debug
debug mode (Debug level + verbose format)
Definition logging.h:102
bool quiet
force console threshold up to Warn
Definition logging.h:103
Compile-time selection of the xDIC reconstruction mode.