1 // Copyright 2002, 2003 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * ale.cc: The main loop of ALE, including the user interface.
26 * ANSI C and POSIX include files.
48 #include "unsupported.h"
49 #include "implication.h"
64 * Device configuration files
67 #include "device/xvp610_320x240.h"
68 #include "device/xvp610_640x480.h"
69 #include "device/ov7620_raw_linear.h"
70 #include "device/canon_300d_raw_linear.h"
71 #include "device/canon_300d_raw_linear_85mm_1_8.h"
72 #include "device/canon_300d_raw_linear_50mm_1_8.h"
73 #include "device/canon_300d_raw_linear_50mm_1_4.h"
74 #include "device/canon_300d_raw_linear_50mm_1_4_1_4.h"
86 char *short_version
= "0.8.3";
88 char *version
= "ALE Version: 0.8.3\n"
90 "File handler: ImageMagick\n"
94 "Color data: " ALE_REAL_PRECISION_STRING
"\n"
95 "Coordinate data: " ALE_POS_PRECISION_STRING
"\n"
101 #if defined NDEBUG && !defined DEBUG
102 "Assertions: Disabled\n"
103 #elif defined DEBUG && !defined NDEBUG
104 "Assertions: Enabled\n"
106 "Assertions: Probably disabled\n"
108 "Assertions: Probably enabled\n"
110 #if OPTIMIZATIONS == 1
111 "Optimizations: Enabled\n"
113 "Optimizations: Disabled\n"
120 * Counts instances of a given option.
122 unsigned int arg_count(int argc
, const char *argv
[], const char *arg
) {
123 unsigned int count
= 0;
124 for (int i
= 0; i
< argc
; i
++) {
125 if (!strcmp(argv
[i
], arg
))
127 else if (!strcmp(argv
[i
], "--"))
134 * Argument prefix counter.
136 * Counts instances of a given option prefix.
138 unsigned int arg_prefix_count(int argc
, const char *argv
[], const char *pfix
) {
139 unsigned int count
= 0;
140 for (int i
= 0; i
< argc
; i
++) {
141 if (!strncmp(argv
[i
], pfix
, strlen(pfix
)))
143 else if (!strcmp(argv
[i
], "--"))
150 * Reallocation function
152 void *local_realloc(void *ptr
, size_t size
) {
153 void *new_ptr
= realloc(ptr
, size
);
156 ui::get()->memory_error_location("main()");
162 * Not enough arguments function.
164 void not_enough(const char *opt_name
) {
165 ui::get()->cli_not_enough(opt_name
);
169 * Bad argument function
171 void bad_arg(const char *opt_name
) {
172 ui::get()->cli_bad_arg(opt_name
);
178 * Does one of two things:
180 * (1) Output version information if called with '--version'
182 * (2) Read options and file arguments, and if the arguments are correct,
183 * write output. If an error is detected, print the usage statement.
187 int main(int argc
, const char *argv
[]){
190 * Initialize help object
193 help
hi(argv
[0], short_version
);
196 * Output version information if --version appears
197 * on the command line.
200 if (arg_count(argc
, argv
, "--version")) {
205 fprintf(stdout
, "%s", version
);
211 * Handle help options
214 if (arg_prefix_count(argc
, argv
, "--h"))
215 for (int i
= 1; i
< argc
; i
++) {
216 int all
= !strcmp(argv
[i
], "--hA");
217 int is_help_option
= !strncmp(argv
[i
], "--h", strlen("--h"));
220 if (!strcmp(argv
[i
], "--hu") || all
)
221 hi
.usage(), found_help
= 1;
222 if (!strcmp(argv
[i
], "--hq") || all
)
223 hi
.defaults(), found_help
= 1;
224 if (!strcmp(argv
[i
], "--hf") || all
)
225 hi
.file(), found_help
= 1;
226 if (!strcmp(argv
[i
], "--he") || all
)
227 hi
.exclusion(), found_help
= 1;
228 if (!strcmp(argv
[i
], "--ha") || all
)
229 hi
.alignment(), found_help
= 1;
230 if (!strcmp(argv
[i
], "--hr") || all
)
231 hi
.rendering(), found_help
= 1;
232 if (!strcmp(argv
[i
], "--hx") || all
)
233 hi
.exposure(), found_help
= 1;
234 if (!strcmp(argv
[i
], "--ht") || all
)
235 hi
.tdf(), found_help
= 1;
236 if (!strcmp(argv
[i
], "--hl") || all
)
237 hi
.filtering(), found_help
= 1;
238 if (!strcmp(argv
[i
], "--hd") || all
)
239 hi
.device(), found_help
= 1;
240 if (!strcmp(argv
[i
], "--hi") || all
)
241 hi
.interface(), found_help
= 1;
242 if (!strcmp(argv
[i
], "--hv") || all
)
243 hi
.visp(), found_help
= 1;
244 if (!strcmp(argv
[i
], "--hc") || all
)
245 hi
.cp(), found_help
= 1;
246 if (!strcmp(argv
[i
], "--h3") || all
)
247 hi
.d3(), found_help
= 1;
248 if (!strcmp(argv
[i
], "--hz") || all
)
249 hi
.undocumented(), found_help
= 1;
251 if (is_help_option
&& !found_help
)
255 * Check for the end-of-options marker, a non-option argument,
256 * or the end of arguments. In all of these cases, we exit.
259 if (!strcmp(argv
[i
], "--")
260 || strncmp(argv
[i
], "--", strlen("--"))
266 * Undocumented projective transformation utility
269 if (arg_count(argc
, argv
, "--ptcalc") > 0) {
270 fprintf(stderr
, "\n\n*** Warning: this feature is not documented ***\n\n");
271 printf("Enter: w h tlx tly blx bly brx bry trx try x y\n\n");
273 double w
, h
, tlx
, tly
, blx
, bly
, brx
, bry
, trx
, tr_y
, x
, y
;
277 if (scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
278 &w
, &h
, &tlx
, &tly
, &blx
, &bly
, &brx
, &bry
, &trx
, &tr_y
, &x
, &y
) != 12) {
280 fprintf(stderr
, "Error reading input.\n");
284 d2::image
*i
= new d2::image_ale_real((int)h
, (int)w
, 3);
285 d2::transformation t
= d2::transformation::gpt_identity(i
, 1);
294 d2::point
a(y
, x
), b
;
296 b
= t
.transform_scaled(a
);
298 printf("TRANSFORM t(a): (%f, %f)\n", (double) b
[1], (double) b
[0]);
300 b
= t
.scaled_inverse_transform(a
);
302 printf("INVERSE t^-1(a): (%f, %f)\n", (double) b
[1], (double) b
[0]);
308 * Flags and variables
311 double scale_factor
= 1;
312 double vise_scale_factor
= 1;
314 double usm_multiplier
= 0.0;
317 struct d2::tload_t
*tload
= NULL
;
318 struct d2::tsave_t
*tsave
= NULL
;
319 struct d3::tload_t
*d3_tload
= NULL
;
320 struct d3::tsave_t
*d3_tsave
= NULL
;
321 int ip_iterations
= 0;
322 int ip_use_median
= 0;
323 enum { psf_linear
, psf_nonlinear
, psf_N
};
324 const char *psf
[psf_N
] = {NULL
, NULL
};
325 const char *device
= NULL
;
327 double psf_match_args
[6];
329 int exposure_register
= 1;
330 const char *wm_filename
= NULL
;
331 int wm_offsetx
, wm_offsety
;
332 double cx_parameter
= 0;
333 double *d3px_parameters
= NULL
;
335 int *ex_parameters
= NULL
;
339 const char *achain_type
= "triangle:2";
340 const char *afilter_type
= "internal";
341 d2::render
**ochain
= NULL
;
342 const char **ochain_names
= NULL
;
343 const char **ochain_types
= NULL
;
344 const char *d3chain_type
= "zero";
346 const char **visp
= NULL
;
348 const char **d3_output
= NULL
;
349 const char **d3_depth
= NULL
;
350 unsigned int d3_count
= 0;
351 double user_view_angle
= 0;
352 int user_bayer
= IMAGE_BAYER_DEFAULT
;
353 d2::pixel exp_mult
= d2::pixel(1, 1, 1);
354 std::map
<const char *, d3::pt
> d3_output_pt
;
355 std::map
<const char *, d3::pt
> d3_depth_pt
;
358 * dchain is ochain[0].
361 ochain
= (d2::render
**) local_realloc(ochain
,
362 (oc_count
+ 1) * sizeof(d2::render
*));
363 ochain_names
= (const char **) local_realloc((void *)ochain_names
,
364 (oc_count
+ 1) * sizeof(const char *));
365 ochain_types
= (const char **) local_realloc((void *)ochain_types
,
366 (oc_count
+ 1) * sizeof(const char *));
368 ochain_types
[0] = "sinc*lanc:8";
373 * Handle default settings
376 if (arg_prefix_count(argc
, argv
, "--q") > 1)
377 ui::get()->error("more than one default setting option --q* was specified");
379 if (arg_count(argc
, argv
, "--q0")) {
380 ochain_types
[0] = "fine:box:1,triangle:2";
381 achain_type
= "triangle:2";
384 d2::image_rw::exp_noscale();
386 } else if (arg_count(argc
, argv
, "--qn")) {
387 ochain_types
[0] = "sinc*lanc:6";
388 achain_type
= "sinc*lanc:6";
391 d2::image_rw::exp_noscale();
393 } else if (arg_count(argc
, argv
, "--q1")) {
394 ochain_types
[0] = "median:fine:sinc*lanc:8,triangle:2";
395 achain_type
= "triangle:2";
398 d2::image_rw::exp_noscale();
400 } else if (arg_count(argc
, argv
, "--q2")) {
401 ochain_types
[0] = "sinc*lanc:8";
402 achain_type
= "sinc*lanc:8";
405 d2::image_rw::exp_noscale();
407 } else if (arg_count(argc
, argv
, "--qr")) {
408 ochain_types
[0] = "sinc*lanc:8";
409 achain_type
= "sinc*lanc:8";
412 d2::image_rw::exp_scale();
418 ochain_types
[0] = "fine:box:1,triangle:2";
419 achain_type
= "triangle:2";
422 d2::image_rw::exp_noscale();
427 * Iterate through arguments until we reach the first file
428 * argument. After the first file argument, we assume that
429 * all following arguments are files.
432 for (int i
= 1; i
< argc
- 1; i
++) {
435 if (!strcmp(argv
[i
], "--q0")
436 || !strcmp(argv
[i
], "--q1")
437 || !strcmp(argv
[i
], "--q2")
438 || !strcmp(argv
[i
], "--qr")
439 || !strcmp(argv
[i
], "--qn")) {
441 * Do nothing. Defaults have already been set.
443 } else if (!strcmp(argv
[i
], "--8bpc")) {
444 d2::image_rw::depth8();
445 } else if (!strcmp(argv
[i
], "--16bpc")) {
446 d2::image_rw::depth16();
447 } else if (!strcmp(argv
[i
], "--plain")) {
448 d2::image_rw::ppm_plain();
449 } else if (!strcmp(argv
[i
], "--raw")) {
450 d2::image_rw::ppm_raw();
451 } else if (!strcmp(argv
[i
], "--auto")) {
452 d2::image_rw::ppm_auto();
453 } else if (!strcmp(argv
[i
], "--align-all")) {
455 } else if (!strcmp(argv
[i
], "--align-green")) {
457 } else if (!strcmp(argv
[i
], "--align-sum")) {
459 } else if (!strcmp(argv
[i
], "--translation")) {
460 d2::align::class_translation();
461 } else if (!strcmp(argv
[i
], "--euclidean")) {
462 d2::align::class_euclidean();
463 } else if (!strcmp(argv
[i
], "--projective")) {
464 d2::align::class_projective();
465 } else if (!strcmp(argv
[i
], "--identity")) {
466 d2::align::initial_default_identity();
467 } else if (!strcmp(argv
[i
], "--follow")) {
468 d2::align::initial_default_follow();
469 } else if (!strcmp(argv
[i
], "--perturb-output")) {
470 d2::align::perturb_output();
471 } else if (!strcmp(argv
[i
], "--perturb-source")) {
472 d2::align::perturb_source();
473 } else if (!strcmp(argv
[i
], "--fail-optimal")) {
474 d2::align::fail_optimal();
475 } else if (!strcmp(argv
[i
], "--fail-default")) {
476 d2::align::fail_default();
477 } else if (!strcmp(argv
[i
], "--no-extend")) {
479 } else if (!strcmp(argv
[i
], "--extend")) {
481 } else if (!strcmp(argv
[i
], "--no-mc")) {
483 } else if (!strcmp(argv
[i
], "--oc")) {
485 } else if (!strcmp(argv
[i
], "--no-oc")) {
487 } else if (!strcmp(argv
[i
], "--gs")) {
491 d2::align::gs(argv
[i
+1]);
494 } else if (!strcmp(argv
[i
], "--gs-mo")) {
496 not_enough("--gs-mo");
498 unsigned int mo_parameter
;
499 if (sscanf(argv
[i
+1], "%u", &mo_parameter
) != 1)
502 d2::align::gs_mo(mo_parameter
);
505 } else if (!strcmp(argv
[i
], "--3ddp") || !strcmp(argv
[i
], "--3dvp")) {
509 * Unsupported configurations
513 unsupported::fornow("3D modeling with Irani-Peleg rendering");
517 unsupported::fornow("3D modeling with unsharp mask");
521 * Check for argument availability
528 * Initialize if necessary
530 * Note: because their existence is checked as an
531 * indicator of the presence of 3D arguments, we
532 * initialize these structures here.
535 if (d3_output
== NULL
) {
536 d3_count
= argc
- (i
+ 2) - 1;
537 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
538 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
541 unsigned int width
, height
;
546 if (sscanf(argv
[i
+1], "%u", &width
) != 1
547 || sscanf(argv
[i
+2], "%u", &height
) != 1
548 || sscanf(argv
[i
+3], "%lf", &view_angle
) != 1
549 || sscanf(argv
[i
+4], "%lf", &x
) != 1
550 || sscanf(argv
[i
+5], "%lf", &y
) != 1
551 || sscanf(argv
[i
+6], "%lf", &z
) != 1
552 || sscanf(argv
[i
+7], "%lf", &P
) != 1
553 || sscanf(argv
[i
+8], "%lf", &Y
) != 1
554 || sscanf(argv
[i
+9], "%lf", &R
) != 1)
557 view_angle
*= M_PI
/ 180;
562 d2::transformation t
=
563 d2::transformation::eu_identity();
564 t
.set_domain(height
, width
);
565 d3::pt
_pt(t
, d3::et(y
, x
, z
, Y
, P
, R
), view_angle
);
567 if (!strcmp(argv
[i
], "--3dvp")) {
568 d3_output_pt
[argv
[i
+10]] = _pt
;
569 } else if (!strcmp(argv
[i
], "--3ddp")) {
570 d3_depth_pt
[argv
[i
+10]] = _pt
;
576 } else if (!strcmp(argv
[i
], "--3dv")) {
579 unsigned int frame_no
;
582 * Unsupported configurations
586 unsupported::fornow("3D modeling with Irani-Peleg rendering");
590 unsupported::fornow("3D modeling with unsharp mask");
594 * Check for argument availability
601 * Initialize if necessary
604 if (d3_output
== NULL
) {
605 d3_count
= argc
- (i
+ 2) - 1;
606 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
607 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
610 if (sscanf(argv
[i
+1], "%d", &frame_no
) != 1)
611 ui::get()->error("--3dv argument 0 must be an integer");
613 if (frame_no
>= d3_count
)
614 ui::get()->error("--3dv argument 0 is too large");
616 if (d3_output
[frame_no
] != NULL
) {
617 unsupported::fornow ("Writing a single 3D view to more than one output file");
620 d3_output
[frame_no
] = argv
[i
+2];
623 } else if (!strcmp(argv
[i
], "--3dd")) {
626 unsigned int frame_no
;
629 * Unsupported configurations
633 unsupported::fornow("3D modeling with Irani-Peleg rendering");
637 unsupported::fornow("3D modeling with unsharp mask");
641 * Check for argument availability
648 * Initialize if necessary
651 if (d3_output
== NULL
) {
652 d3_count
= argc
- (i
+ 2) - 1;
653 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
654 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
657 if (sscanf(argv
[i
+1], "%d", &frame_no
) != 1)
658 ui::get()->error("--3dd argument 0 must be an integer");
660 if (frame_no
>= d3_count
)
661 ui::get()->error("--3dd argument 0 is too large");
663 if (d3_depth
[frame_no
] != NULL
) {
664 unsupported::fornow ("Writing a single frame's depth info to more than one output file");
667 d3_depth
[frame_no
] = argv
[i
+2];
671 } else if (!strcmp(argv
[i
], "--view-angle")) {
673 not_enough("--view-angle");
676 sscanf(argv
[i
+1], "%lf", &va_parameter
);
678 user_view_angle
= va_parameter
* M_PI
/ 180;
679 } else if (!strcmp(argv
[i
], "--cpf-load")) {
681 not_enough("--cpf-load");
683 d3::cpf::init_loadfile(argv
[i
+1]);
685 } else if (!strcmp(argv
[i
], "--ui=stream")) {
687 } else if (!strcmp(argv
[i
], "--ui=tty")) {
689 } else if (!strcmp(argv
[i
], "--et")) {
695 sscanf(argv
[i
+1], "%lf", &et_parameter
);
697 d3::scene::et(et_parameter
);
699 } else if (!strcmp(argv
[i
], "--st")) {
704 sscanf(argv
[i
+1], "%lf", &st_parameter
);
706 d3::cpf::st(st_parameter
);
707 } else if (!strcmp(argv
[i
], "--di-lower")) {
709 not_enough("--di-lower");
712 sscanf(argv
[i
+1], "%lf", &di_parameter
);
714 d3::scene::di_lower(di_parameter
);
715 } else if (!strcmp(argv
[i
], "--rc")) {
720 sscanf(argv
[i
+1], "%lf", &rc_parameter
);
722 d3::scene::rc(rc_parameter
);
723 } else if (!strcmp(argv
[i
], "--do-try")) {
725 not_enough("--do-try");
728 sscanf(argv
[i
+1], "%lf", &do_parameter
);
730 d3::scene::do_try(do_parameter
);
731 } else if (!strcmp(argv
[i
], "--di-upper")) {
733 not_enough("--di-upper");
735 double dgi_parameter
;
736 sscanf(argv
[i
+1], "%lf", &dgi_parameter
);
738 d3::scene::di_upper(dgi_parameter
);
739 } else if (!strcmp(argv
[i
], "--fc")) {
744 sscanf(argv
[i
+1], "%lf", &fc_parameter
);
746 d3::scene::fc(fc_parameter
);
747 } else if (!strcmp(argv
[i
], "--ecm")) {
748 unsupported::discontinued("--ecm <x>");
749 } else if (!strcmp(argv
[i
], "--acm")) {
750 unsupported::discontinued("--acm <x>");
751 } else if (!strcmp(argv
[i
], "--def-nn")) {
753 not_enough("--def-nn");
756 sscanf(argv
[i
+1], "%lf", &nn_parameter
);
758 d2::image_rw::def_nn(nn_parameter
);
760 if (nn_parameter
> 2) {
761 fprintf(stderr
, "\n\n*** Warning: --def-nn implementation is currently "
762 "inefficient for large radii. ***\n\n");
765 } else if (!strcmp(argv
[i
], "--mc")) {
770 sscanf(argv
[i
+1], "%lf", &mc_parameter
);
773 d2::align::mc(mc_parameter
);
775 } else if (!strcmp(argv
[i
], "--fx")) {
781 sscanf(argv
[i
+1], "%lf", &fx_parameter
);
783 d3::scene::fx(fx_parameter
);
785 } else if (!strcmp(argv
[i
], "--tcem")) {
788 not_enough("--tcem");
790 double tcem_parameter
;
791 sscanf(argv
[i
+1], "%lf", &tcem_parameter
);
793 d3::scene::tcem(tcem_parameter
);
795 } else if (!strcmp(argv
[i
], "--oui")) {
800 unsigned int oui_parameter
;
801 sscanf(argv
[i
+1], "%u", &oui_parameter
);
803 d3::scene::oui(oui_parameter
);
805 } else if (!strcmp(argv
[i
], "--pa")) {
810 unsigned int pa_parameter
;
811 sscanf(argv
[i
+1], "%u", &pa_parameter
);
813 d3::scene::pa(pa_parameter
);
815 } else if (!strcmp(argv
[i
], "--pc")) {
820 d3::scene::pc(argv
[i
+1]);
823 } else if (!strcmp(argv
[i
], "--cw")) {
824 d2::align::certainty_weighted(1);
825 } else if (!strcmp(argv
[i
], "--no-cw")) {
826 d2::align::certainty_weighted(0);
827 } else if (!strcmp(argv
[i
], "--wm")) {
828 if (wm_filename
!= NULL
)
829 ui::get()->error("only one weight map can be specified");
833 wm_filename
= argv
[i
+1];
835 if (sscanf(argv
[i
+2], "%d", &wm_offsetx
) != 1)
836 ui::get()->error("--wm x-argument must be an integer");
838 if (sscanf(argv
[i
+3], "%d", &wm_offsety
) != 1)
839 ui::get()->error("--wm y-argument must be an integer");
843 } else if (!strcmp(argv
[i
], "--fl")) {
847 if (sscanf(argv
[i
+1], "%lf", &h
) != 1)
848 ui::get()->error("--fl h-argument must be numerical");
849 if (sscanf(argv
[i
+2], "%lf", &v
) != 1)
850 ui::get()->error("--fl v-argument must be numerical");
851 if (sscanf(argv
[i
+3], "%lf", &a
) != 1)
852 ui::get()->error("--fl a-argument must be numerical");
855 d2::align::set_frequency_cut(h
, v
, a
);
857 ui::get()->error_hint("--fl is not supported", "rebuild ALE with FFTW=1");
859 } else if (!strcmp(argv
[i
], "--wmx")) {
863 d2::align::set_wmx(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
865 ui::get()->error_hint("--wmx is not supported", "rebuild ALE with POSIX=1");
868 } else if (!strcmp(argv
[i
], "--flshow")) {
870 not_enough("--flshow");
871 d2::align::set_fl_show(argv
[i
+1]);
873 } else if (!strcmp(argv
[i
], "--3dpx")) {
875 not_enough("--3dpx");
877 d3px_parameters
= (double *) local_realloc(d3px_parameters
, (d3px_count
+ 1) * 6 * sizeof(double));
879 for (int param
= 0; param
< 6; param
++)
880 if (sscanf(argv
[i
+ param
+ 1], "%lf", &(d3px_parameters
[6 * d3px_count
+ param
])) != 1)
884 * Swap x and y, since their internal meanings differ from their external meanings.
887 for (int param
= 0; param
< 2; param
++) {
888 double temp
= d3px_parameters
[6 * d3px_count
+ 2 + param
];
889 d3px_parameters
[6 * d3px_count
+ 2 + param
] = d3px_parameters
[6 * d3px_count
+ 0 + param
];
890 d3px_parameters
[6 * d3px_count
+ 0 + param
] = temp
;
900 } else if (!strcmp(argv
[i
], "--ex")) {
904 ex_parameters
= (int *) local_realloc(ex_parameters
, (ex_count
+ 1) * 6 * sizeof(int));
906 for (int param
= 0; param
< 6; param
++)
907 if (sscanf(argv
[i
+ param
+ 1], "%d", &(ex_parameters
[6 * ex_count
+ param
])) != 1)
911 * Swap x and y, since their internal meanings differ from their external meanings.
914 for (int param
= 0; param
< 2; param
++) {
915 int temp
= ex_parameters
[6 * ex_count
+ 2 + param
];
916 ex_parameters
[6 * ex_count
+ 2 + param
] = ex_parameters
[6 * ex_count
+ 0 + param
];
917 ex_parameters
[6 * ex_count
+ 0 + param
] = temp
;
927 } else if (!strcmp(argv
[i
], "--crop")) {
929 not_enough("--crop");
931 ex_parameters
= (int *) local_realloc(ex_parameters
, (ex_count
+ 4) * 6 * sizeof(int));
934 for (int param
= 0; param
< 6; param
++)
935 if (sscanf(argv
[i
+ param
+ 1], "%d", &(crop_args
[param
])) != 1)
939 * Construct exclusion regions from the crop area,
940 * swapping x and y, since their internal meanings
941 * differ from their external meanings.
945 * Exclusion region 1: low x
948 ex_parameters
[6 * ex_count
+ 0] = INT_MIN
;
949 ex_parameters
[6 * ex_count
+ 1] = crop_args
[2] - 1;
950 ex_parameters
[6 * ex_count
+ 2] = INT_MIN
;
951 ex_parameters
[6 * ex_count
+ 3] = INT_MAX
;
952 ex_parameters
[6 * ex_count
+ 4] = crop_args
[4];
953 ex_parameters
[6 * ex_count
+ 5] = crop_args
[5];
956 * Exclusion region 2: low y
959 ex_parameters
[6 * ex_count
+ 6] = INT_MIN
;
960 ex_parameters
[6 * ex_count
+ 7] = INT_MAX
;
961 ex_parameters
[6 * ex_count
+ 8] = INT_MIN
;
962 ex_parameters
[6 * ex_count
+ 9] = crop_args
[0] - 1;
963 ex_parameters
[6 * ex_count
+ 10] = crop_args
[4];
964 ex_parameters
[6 * ex_count
+ 11] = crop_args
[5];
967 * Exclusion region 3: high y
970 ex_parameters
[6 * ex_count
+ 12] = INT_MIN
;
971 ex_parameters
[6 * ex_count
+ 13] = INT_MAX
;
972 ex_parameters
[6 * ex_count
+ 14] = crop_args
[1] + 1;
973 ex_parameters
[6 * ex_count
+ 15] = INT_MAX
;
974 ex_parameters
[6 * ex_count
+ 16] = crop_args
[4];
975 ex_parameters
[6 * ex_count
+ 17] = crop_args
[5];
978 * Exclusion region 4: high x
981 ex_parameters
[6 * ex_count
+ 18] = crop_args
[3] + 1;
982 ex_parameters
[6 * ex_count
+ 19] = INT_MAX
;
983 ex_parameters
[6 * ex_count
+ 20] = INT_MIN
;
984 ex_parameters
[6 * ex_count
+ 21] = INT_MAX
;
985 ex_parameters
[6 * ex_count
+ 22] = crop_args
[4];
986 ex_parameters
[6 * ex_count
+ 23] = crop_args
[5];
994 } else if (!strcmp(argv
[i
], "--exshow")) {
996 } else if (!strcmp(argv
[i
], "--wt")) {
1002 if (sscanf(argv
[i
+ 1], "%lf", &wt
) != 1)
1005 d2::render::set_wt(wt
);
1007 } else if (!strcmp(argv
[i
], "--3d-chain")) {
1009 not_enough("--3d-chain");
1010 d3chain_type
= argv
[i
+1];
1012 } else if (!strcmp(argv
[i
], "--dchain")) {
1014 not_enough("--dchain");
1015 ochain_types
[0] = argv
[i
+1];
1017 } else if (!strcmp(argv
[i
], "--achain")) {
1019 not_enough("--achain");
1020 achain_type
= argv
[i
+1];
1022 } else if (!strcmp(argv
[i
], "--afilter")) {
1024 not_enough("--afilter");
1025 afilter_type
= argv
[i
+1];
1027 } else if (!strcmp(argv
[i
], "--ochain")) {
1029 not_enough("--ochain");
1031 ochain
= (d2::render
**) local_realloc(ochain
,
1032 (oc_count
+ 1) * sizeof(d2::render
*));
1033 ochain_names
= (const char **) local_realloc((void *)ochain_names
,
1034 (oc_count
+ 1) * sizeof(const char *));
1035 ochain_types
= (const char **) local_realloc((void *)ochain_types
,
1036 (oc_count
+ 1) * sizeof(const char *));
1038 ochain_types
[oc_count
] = argv
[i
+1];
1039 ochain_names
[oc_count
] = argv
[i
+2];
1043 } else if (!strcmp(argv
[i
], "--visp")) {
1045 not_enough("--visp");
1047 visp
= (const char **) local_realloc((void *)visp
, 4 *
1048 (vise_count
+ 1) * sizeof(const char *));
1050 for (int param
= 0; param
< 4; param
++)
1051 visp
[vise_count
* 4 + param
] = argv
[i
+ 1 + param
];
1055 } else if (!strcmp(argv
[i
], "--cx")) {
1060 sscanf(argv
[i
+1], "%lf", &cx_parameter
);
1063 } else if (!strcmp(argv
[i
], "--no-cx")) {
1065 } else if (!strcmp(argv
[i
], "--ip")) {
1066 unsupported::discontinued("--ip <r> <i>", "--lpsf box=<r> --ips <i>");
1067 } else if (!strcmp(argv
[i
], "--bayer")) {
1069 not_enough("--bayer");
1072 * External order is clockwise from top-left. Internal
1073 * order is counter-clockwise from top-left.
1076 if (!strcmp(argv
[i
+1], "rgbg")) {
1077 user_bayer
= IMAGE_BAYER_RGBG
;
1078 } else if (!strcmp(argv
[i
+1], "bgrg")) {
1079 user_bayer
= IMAGE_BAYER_BGRG
;
1080 } else if (!strcmp(argv
[i
+1], "gbgr")) {
1081 user_bayer
= IMAGE_BAYER_GRGB
;
1082 } else if (!strcmp(argv
[i
+1], "grgb")) {
1083 user_bayer
= IMAGE_BAYER_GBGR
;
1084 } else if (!strcmp(argv
[i
+1], "none")) {
1085 user_bayer
= IMAGE_BAYER_NONE
;
1090 } else if (!strcmp(argv
[i
], "--lpsf")) {
1092 not_enough("--lpsf");
1094 psf
[psf_linear
] = argv
[i
+1];
1096 } else if (!strcmp(argv
[i
], "--nlpsf")) {
1098 not_enough("--nlpsf");
1100 psf
[psf_nonlinear
] = argv
[i
+1];
1103 } else if (!strcmp(argv
[i
], "--psf-match")) {
1105 not_enough("--psf-match");
1109 for (int index
= 0; index
< 6; index
++) {
1110 if (sscanf(argv
[i
+ 1], "%lf", &psf_match_args
[index
]) != 1)
1111 bad_arg("--psf-match");
1115 } else if (!strcmp(argv
[i
], "--device")) {
1117 not_enough("--device");
1123 } else if (!strcmp(argv
[i
], "--usm")) {
1125 if (d3_output
!= NULL
)
1126 unsupported::fornow("3D modeling with unsharp mask");
1129 not_enough("--usm");
1131 sscanf(argv
[i
+1], "%lf", &usm_multiplier
);
1135 } else if (!strcmp(argv
[i
], "--ipr")) {
1138 not_enough("--ipr");
1140 if (sscanf(argv
[i
+1], "%d", &ip_iterations
) != 1)
1141 ui::get()->error("--ipr requires an integer argument");
1143 ui::get()->warn("--ipr is deprecated. Use --ips instead");
1146 } else if (!strcmp(argv
[i
], "--cpp-err-median")) {
1147 d3::cpf::err_median();
1148 } else if (!strcmp(argv
[i
], "--cpp-err-mean")) {
1149 d3::cpf::err_mean();
1150 } else if (!strcmp(argv
[i
], "--vp-adjust")) {
1151 d3::align::vp_adjust();
1152 } else if (!strcmp(argv
[i
], "--vp-noadjust")) {
1153 d3::align::vp_noadjust();
1154 } else if (!strcmp(argv
[i
], "--vo-adjust")) {
1155 d3::align::vo_adjust();
1156 } else if (!strcmp(argv
[i
], "--vo-noadjust")) {
1157 d3::align::vo_noadjust();
1158 } else if (!strcmp(argv
[i
], "--ip-mean")) {
1160 } else if (!strcmp(argv
[i
], "--ip-median")) {
1162 } else if (!strcmp(argv
[i
], "--ips")) {
1165 not_enough("--ips");
1167 if (sscanf(argv
[i
+1], "%d", &ip_iterations
) != 1)
1168 ui::get()->error("--ips requires an integer argument");
1170 } else if (!strcmp(argv
[i
], "--ipc")) {
1171 unsupported::discontinued("--ipc <c> <i>", "--ips <i> --lpsf <c>", "--ips <i> --device <c>");
1172 } else if (!strcmp(argv
[i
], "--exp-extend")) {
1173 d2::image_rw::exp_scale();
1174 } else if (!strcmp(argv
[i
], "--exp-noextend")) {
1175 d2::image_rw::exp_noscale();
1176 } else if (!strcmp(argv
[i
], "--exp-register")) {
1177 exposure_register
= 1;
1178 d2::align::exp_register();
1179 } else if (!strcmp(argv
[i
], "--exp-noregister")) {
1180 exposure_register
= 0;
1181 d2::align::exp_noregister();
1182 } else if (!strcmp(argv
[i
], "--exp-meta-only")) {
1183 exposure_register
= 2;
1184 d2::align::exp_meta_only();
1185 } else if (!strcmp(argv
[i
], "--drizzle-only")) {
1186 unsupported::discontinued("--drizzle-only", "--dchain box:1");
1187 } else if (!strcmp(argv
[i
], "--subspace-traverse")) {
1188 unsupported::undocumented("--subspace-traverse");
1189 d3::scene::set_subspace_traverse();
1190 } else if (!strcmp(argv
[i
], "--occ-norm")) {
1192 } else if (!strcmp(argv
[i
], "--occ-nonorm")) {
1194 } else if (!strcmp(argv
[i
], "--inc")) {
1196 } else if (!strcmp(argv
[i
], "--no-inc")) {
1198 } else if (!strncmp(argv
[i
], "--exp-mult=", strlen("--exp-mult="))) {
1199 double exp_c
, exp_r
, exp_b
;
1200 sscanf(argv
[i
] + strlen("--exp-mult="), "%lf,%lf,%lf", &exp_c
, &exp_r
, &exp_b
);
1201 exp_mult
= d2::pixel(1/(exp_r
* exp_c
), 1/exp_c
, 1/(exp_b
* exp_c
));
1202 } else if (!strncmp(argv
[i
], "--visp-scale=", strlen("--visp-scale="))) {
1204 sscanf(argv
[i
] + strlen("--visp-scale="), "%lf", &vise_scale_factor
);
1206 if (vise_scale_factor
<= 0.0)
1207 ui::get()->error("VISP scale must be greater than zero");
1209 if (!finite(vise_scale_factor
))
1210 ui::get()->error("VISP scale must be finite");
1212 } else if (!strncmp(argv
[i
], "--scale=", strlen("--scale="))) {
1214 sscanf(argv
[i
] + strlen("--scale="), "%lf", &scale_factor
);
1216 if (scale_factor
<= 0)
1217 ui::get()->error("Scale factor must be greater than zero");
1219 if (!finite(scale_factor
))
1220 ui::get()->error("Scale factor must be finite");
1222 } else if (!strncmp(argv
[i
], "--metric=", strlen("--metric="))) {
1224 sscanf(argv
[i
] + strlen("--metric="), "%lf", &metric
);
1225 d2::align::set_metric_exponent(metric
);
1226 } else if (!strncmp(argv
[i
], "--threshold=", strlen("--threshold="))) {
1227 double match_threshold
;
1228 sscanf(argv
[i
] + strlen("--threshold="), "%lf", &match_threshold
);
1229 d2::align::set_match_threshold(match_threshold
);
1230 } else if (!strncmp(argv
[i
], "--drizzle-diam=", strlen("--drizzle-diam="))) {
1231 unsupported::discontinued("--drizzle-diam=<x>", "--dchain box:1");
1232 // sscanf(argv[i] + strlen("--drizzle-diam="), "%lf", &drizzle_radius);
1233 // drizzle_radius /= 2;
1234 } else if (!strncmp(argv
[i
], "--perturb-upper=", strlen("--perturb-upper="))) {
1235 double perturb_upper
;
1237 sscanf(argv
[i
] + strlen("--perturb-upper="), "%lf%n", &perturb_upper
,
1239 if (*(argv
[i
] + strlen("--perturb-upper=") + characters
) == '%')
1240 d2::align::set_perturb_upper(perturb_upper
, 1);
1242 d2::align::set_perturb_upper(perturb_upper
, 0);
1243 } else if (!strncmp(argv
[i
], "--perturb-lower=", strlen("--perturb-lower="))) {
1244 double perturb_lower
;
1246 sscanf(argv
[i
] + strlen("--perturb-lower="), "%lf%n", &perturb_lower
,
1248 if (perturb_lower
<= 0)
1249 ui::get()->error("--perturb-lower= value is non-positive");
1251 if (*(argv
[i
] + strlen("--perturb-lower=") + characters
) == '%')
1252 d2::align::set_perturb_lower(perturb_lower
, 1);
1254 d2::align::set_perturb_lower(perturb_lower
, 0);
1255 } else if (!strncmp(argv
[i
], "--stepsize=", strlen("--stepsize="))) {
1256 double perturb_lower
;
1257 ui::get()->warn("--stepsize is deprecated. Use --perturb-lower instead");
1258 sscanf(argv
[i
] + strlen("--stepsize="), "%lf", &perturb_lower
);
1259 d2::align::set_perturb_lower(perturb_lower
, 0);
1260 } else if (!strncmp(argv
[i
], "--va-upper=", strlen("--va-upper="))) {
1263 sscanf(argv
[i
] + strlen("--va-upper="), "%lf%n", &va_upper
,
1265 if (*(argv
[i
] + strlen("--va-upper=") + characters
) == '%')
1266 ui::get()->error("--va-upper= does not accept '%' arguments\n");
1268 d3::cpf::set_va_upper(va_upper
);
1269 } else if (!strncmp(argv
[i
], "--cpp-upper=", strlen("--cpp-upper="))) {
1270 double perturb_upper
;
1272 sscanf(argv
[i
] + strlen("--cpp-upper="), "%lf%n", &perturb_upper
,
1274 if (*(argv
[i
] + strlen("--cpp-upper=") + characters
) == '%')
1275 ui::get()->error("--cpp-upper= does not currently accept '%' arguments\n");
1277 d3::cpf::set_cpp_upper(perturb_upper
);
1278 } else if (!strncmp(argv
[i
], "--cpp-lower=", strlen("--cpp-lower="))) {
1279 double perturb_lower
;
1281 sscanf(argv
[i
] + strlen("--cpp-lower="), "%lf%n", &perturb_lower
,
1283 if (*(argv
[i
] + strlen("--cpp-lower=") + characters
) == '%')
1284 ui::get()->error("--cpp-lower= does not currently accept '%' arguments\n");
1286 d3::cpf::set_cpp_lower(perturb_lower
);
1287 } else if (!strncmp(argv
[i
], "--hf-enhance=", strlen("--hf-enhance="))) {
1288 unsupported::discontinued("--hf-enhance=<x>");
1289 } else if (!strncmp(argv
[i
], "--rot-upper=", strlen("--rot-upper="))) {
1291 sscanf(argv
[i
] + strlen("--rot-upper="), "%lf", &rot_max
);
1292 d2::align::set_rot_max((int) floor(rot_max
));
1293 } else if (!strncmp(argv
[i
], "--bda-mult=", strlen("--bda-mult="))) {
1295 sscanf(argv
[i
] + strlen("--bda-mult="), "%lf", &bda_mult
);
1296 d2::align::set_bda_mult(bda_mult
);
1297 } else if (!strncmp(argv
[i
], "--bda-rate=", strlen("--bda-rate="))) {
1299 sscanf(argv
[i
] + strlen("--bda-rate="), "%lf", &bda_rate
);
1300 d2::align::set_bda_rate(bda_rate
);
1301 } else if (!strncmp(argv
[i
], "--lod-max=", strlen("--lod-max="))) {
1303 sscanf(argv
[i
] + strlen("--lod-max="), "%lf", &lod_max
);
1304 d2::align::set_lod_max((int) floor(lod_max
));
1305 } else if (!strncmp(argv
[i
], "--cpf-load=", strlen("--cpf-load="))) {
1306 d3::cpf::init_loadfile(argv
[i
] + strlen("--cpf-load="));
1308 } else if (!strncmp(argv
[i
], "--model-load=", strlen("--model-load="))) {
1309 d3::scene::load_model(argv
[i
] + strlen("--model-load="));
1310 } else if (!strncmp(argv
[i
], "--model-save=", strlen("--model-save="))) {
1311 d3::scene::save_model(argv
[i
] + strlen("--model-save="));
1313 } else if (!strncmp(argv
[i
], "--trans-load=", strlen("--trans-load="))) {
1314 d2::tload_delete(tload
);
1315 tload
= d2::tload_new(argv
[i
] + strlen("--trans-load="));
1316 d2::align::set_tload(tload
);
1317 } else if (!strncmp(argv
[i
], "--trans-save=", strlen("--trans-save="))) {
1318 tsave_delete(tsave
);
1319 tsave
= d2::tsave_new(argv
[i
] + strlen("--trans-save="));
1320 d2::align::set_tsave(tsave
);
1321 } else if (!strncmp(argv
[i
], "--3d-trans-load=", strlen("--3d-trans-load="))) {
1322 d3::tload_delete(d3_tload
);
1323 d3_tload
= d3::tload_new(argv
[i
] + strlen("--3d-trans-load="));
1324 d3::align::set_tload(d3_tload
);
1325 } else if (!strncmp(argv
[i
], "--3d-trans-save=", strlen("--3d-trans-save="))) {
1326 d3::tsave_delete(d3_tsave
);
1327 d3_tsave
= d3::tsave_new(argv
[i
] + strlen("--3d-trans-save="));
1328 d3::align::set_tsave(d3_tsave
);
1332 * Trap illegal options and end-of-option indicators.
1335 if (!strcmp(argv
[i
], "--"))
1337 else if (!strncmp(argv
[i
], "--", strlen("--")))
1338 ui::get()->illegal_option(argv
[i
]);
1341 * Apply implication logic.
1344 if (extend
== 0 && vise_count
!= 0) {
1345 implication::changed("VISP requires increased image extents.",
1346 "Image extension is now enabled.",
1351 if (psf_match
&& ex_count
)
1352 unsupported::fornow("PSF calibration with exclusion regions.");
1355 if (d3_output
!= NULL
&& ip_iterations
!= 0)
1356 unsupported::fornow("3D modeling with Irani-Peleg rendering");
1359 if (extend
== 0 && d3_output
!= NULL
) {
1360 implication::changed("3D modeling requires increased image extents.",
1361 "Image extension is now enabled.",
1367 if (cx_parameter
!= 0 && !exposure_register
) {
1368 implication::changed("Certainty-based rendering requires exposure registration.",
1369 "Exposure registration is now enabled.",
1371 d2::align::exp_register();
1372 exposure_register
= 1;
1376 * Set alignment class exclusion region static variables
1379 d2::align::set_exclusion(ex_parameters
, ex_count
);
1382 * Initialize renderer class statics.
1385 d2::render::render_init(ex_count
, ex_parameters
, ex_show
, extend
, scale_factor
);
1391 d2::exposure::set_confidence(cx_parameter
);
1394 * Keep transformations for Irani-Peleg, psf-match, and
1398 if (ip_iterations
> 0 || psf_match
|| vise_count
> 0) {
1403 * Initialize device-specific variables
1406 d2::psf
*device_response
[psf_N
] = { NULL
, NULL
};
1407 d2::exposure
**input_exposure
= NULL
;
1408 ale_pos view_angle
= 43.7 * M_PI
/ 180;
1409 // ale_pos view_angle = 90 * M_PI / 180;
1410 input_exposure
= (d2::exposure
**)
1411 malloc((argc
- i
- 1) * sizeof(d2::exposure
*));
1413 if (device
!= NULL
) {
1414 if (!strcmp(device
, "xvp610_640x480")) {
1415 device_response
[psf_linear
] = new xvp610_640x480::lpsf();
1416 device_response
[psf_nonlinear
] = new xvp610_640x480::nlpsf();
1417 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1418 input_exposure
[ii
] = new xvp610_640x480::exposure();
1419 view_angle
= xvp610_640x480::view_angle();
1420 } else if (!strcmp(device
, "xvp610_320x240")) {
1421 device_response
[psf_linear
] = new xvp610_320x240::lpsf();
1422 device_response
[psf_nonlinear
] = new xvp610_320x240::nlpsf();
1423 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1424 input_exposure
[ii
] = new xvp610_320x240::exposure();
1425 view_angle
= xvp610_320x240::view_angle();
1426 } else if (!strcmp(device
, "ov7620_raw_linear")) {
1427 device_response
[psf_linear
] = new ov7620_raw_linear::lpsf();
1428 device_response
[psf_nonlinear
] = NULL
;
1429 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1430 input_exposure
[ii
] = new ov7620_raw_linear::exposure();
1431 d2::image_rw::set_default_bayer(IMAGE_BAYER_BGRG
);
1432 } else if (!strcmp(device
, "canon_300d_raw_linear")) {
1433 device_response
[psf_linear
] = new canon_300d_raw_linear::lpsf();
1434 device_response
[psf_nonlinear
] = NULL
;
1435 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1436 input_exposure
[ii
] = new canon_300d_raw_linear::exposure();
1437 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1438 } else if (!strcmp(device
, "canon_300d_raw_linear+85mm_1.8")) {
1439 device_response
[psf_linear
] = new canon_300d_raw_linear_85mm_1_8::lpsf();
1440 device_response
[psf_nonlinear
] = NULL
;
1441 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1442 input_exposure
[ii
] = new canon_300d_raw_linear_85mm_1_8::exposure();
1443 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1444 view_angle
= canon_300d_raw_linear_85mm_1_8::view_angle();
1445 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.8")) {
1446 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_8::lpsf();
1447 device_response
[psf_nonlinear
] = NULL
;
1448 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1449 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_8::exposure();
1450 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1451 view_angle
= canon_300d_raw_linear_50mm_1_8::view_angle();
1452 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.4")) {
1453 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_4::lpsf();
1454 device_response
[psf_nonlinear
] = NULL
;
1455 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1456 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_4::exposure();
1457 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1458 view_angle
= canon_300d_raw_linear_50mm_1_4::view_angle();
1459 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.4@1.4")) {
1460 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_4_1_4::lpsf();
1461 device_response
[psf_nonlinear
] = NULL
;
1462 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1463 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_4_1_4::exposure();
1464 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1465 view_angle
= canon_300d_raw_linear_50mm_1_4_1_4::view_angle();
1467 ui::get()->unknown_device(device
);
1470 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1471 input_exposure
[ii
] = new d2::exposure_default();
1475 * User-specified variables.
1478 if (user_view_angle
!= 0) {
1479 view_angle
= user_view_angle
;
1482 if (user_bayer
!= IMAGE_BAYER_DEFAULT
) {
1483 d2::image_rw::set_default_bayer(user_bayer
);
1487 * PSF-match exposure.
1490 delete input_exposure
[argc
- i
- 2];
1491 input_exposure
[argc
- i
- 2] = new d2::exposure_default();
1495 * Initialize output exposure
1498 d2::exposure
*output_exposure
= new d2::exposure_default();
1499 output_exposure
->set_multiplier(exp_mult
);
1502 * Configure the response function.
1505 d2::psf
*response
[2] = {NULL
, NULL
};
1507 for (int n
= 0; n
< psf_N
; n
++ ) {
1508 if (psf
[n
] != NULL
) {
1510 response
[n
] = d2::psf_parse::get((n
== psf_linear
), psf
[n
]);
1512 } else if (device_response
[n
] != NULL
) {
1515 * Device-specific response
1518 response
[n
] = device_response
[n
];
1523 * Default point-spread function.
1526 if (n
== psf_linear
) {
1529 * Default lpsf is a box filter
1530 * of diameter 1.0 (radius
1534 response
[n
] = new d2::box(0.5);
1536 } else if (n
== psf_nonlinear
) {
1539 * nlpsf is disabled by default.
1548 * First file argument. Print general file information as well
1549 * as information specific to this argument. Initialize image
1554 * There should be at least two file arguments.
1557 if (i
>= argc
- 1) {
1562 d2::image_rw::init(argc
- i
- 1, argv
+ i
, argv
[argc
- 1], input_exposure
, output_exposure
);
1563 ochain_names
[0] = argv
[argc
- 1];
1566 * Handle control point data for alignment
1568 d2::align::set_cp_count(d3::cpf::count());
1569 for (unsigned int ii
= 0; ii
< d3::cpf::count(); ii
++)
1570 d2::align::set_cp(ii
, d3::cpf::get_2d(ii
));
1573 * PSF-match bayer patterns.
1577 d2::image_rw::set_specific_bayer(argc
- i
- 2, IMAGE_BAYER_NONE
);
1581 * Handle alignment weight map, if necessary
1584 if (wm_filename
!= NULL
) {
1585 d2::image
*weight_map
;
1586 weight_map
= d2::image_rw::read_image(wm_filename
, new d2::exposure_linear());
1587 weight_map
->set_offset(wm_offsety
, wm_offsetx
);
1588 d2::align::set_weight_map(weight_map
);
1592 * Write comment information about original frame and
1593 * target image to the transformation save file, if we
1597 const d2::image
*im
= d2::image_rw::open(0);
1598 tsave_orig(tsave
, argv
[i
], im
->avg_channel_magnitude());
1599 tsave_target(tsave
, argv
[argc
- 1]);
1600 d2::image_rw::close(0);
1603 * Initialize alignment interpolant.
1606 if (afilter_type
!= "internal")
1607 d2::align::set_interpolant(d2::render_parse::get_SSF(afilter_type
));
1610 * Initialize achain and ochain.
1613 achain
= d2::render_parse::get(achain_type
);
1615 for (int chain
= 0; chain
< oc_count
; chain
++)
1616 ochain
[chain
] = d2::render_parse::get(ochain_types
[chain
]);
1619 * Use merged renderings as reference images in
1623 d2::align::set_reference(achain
);
1626 * Tell the alignment class about the scale factor.
1629 d2::align::set_scale(scale_factor
);
1635 d2::vise_core::set_scale(vise_scale_factor
);
1637 for (int opt
= 0; opt
< vise_count
; opt
++) {
1638 d2::vise_core::add(d2::render_parse::get(visp
[opt
* 4 + 0]),
1645 * Initialize non-incremental renderers
1649 if (usm_multiplier
!= 0) {
1652 * Unsharp Mask renderer
1655 ochain
[0] = new d2::usm(ochain
[0], scale_factor
,
1656 usm_multiplier
, inc
, response
[psf_linear
],
1657 response
[psf_nonlinear
], &input_exposure
[0]);
1664 * Point-spread function calibration renderer.
1665 * This renderer does not produce image output.
1666 * It is reserved for use with the point-spread
1667 * function calibration script
1668 * ale-psf-calibrate.
1671 ochain
[0] = new d2::psf_calibrate(ochain
[0],
1672 1, inc
, response
[psf_linear
],
1673 response
[psf_nonlinear
],
1676 } else if (ip_iterations
!= 0) {
1679 * Irani-Peleg renderer
1682 ochain
[0] = new d2::ipc( ochain
[0], ip_iterations
,
1683 inc
, response
[psf_linear
],
1684 response
[psf_nonlinear
],
1685 (exposure_register
== 1), ip_use_median
);
1689 * Handle the original frame.
1692 ui::get()->original_frame_start(argv
[i
]);
1694 for (int opt
= 0; opt
< oc_count
; opt
++) {
1695 ui::get()->set_orender_current(opt
);
1696 ochain
[opt
]->sync(0);
1698 ui::get()->writing_output(opt
);
1699 d2::image_rw::write_image(ochain_names
[opt
],
1700 ochain
[opt
]->get_image(0));
1704 d2::vise_core::frame_queue_add(0);
1706 ui::get()->original_frame_done();
1709 * Handle supplemental frames.
1712 for (unsigned int j
= 1; j
< d2::image_rw::count(); j
++) {
1714 const char *name
= d2::image_rw::name(j
);
1716 ui::get()->supplemental_frame_start(name
);
1719 * Write comment information about the
1720 * supplemental frame to the transformation
1721 * save file, if we have one.
1724 tsave_info (tsave
, name
);
1726 const d2::image
*im
= d2::image_rw::open(j
);
1727 d2::pixel apm
= im
->avg_channel_magnitude();
1728 tsave_apm(tsave
, apm
[0], apm
[1], apm
[2]);
1729 d2::image_rw::close(j
);
1731 for (int opt
= 0; opt
< oc_count
; opt
++) {
1732 ui::get()->set_orender_current(opt
);
1733 ochain
[opt
]->sync(j
);
1735 ui::get()->writing_output(opt
);
1736 d2::image_rw::write_image(ochain_names
[opt
],
1737 ochain
[opt
]->get_image(j
));
1741 d2::vise_core::frame_queue_add(j
);
1743 ui::get()->supplemental_frame_done();
1747 * Do any post-processing and output final image
1749 * XXX: note that non-incremental renderers currently
1750 * return zero for ochain[0]->sync(), since they write
1751 * output internally when inc != 0.
1754 for (int opt
= 0; opt
< oc_count
; opt
++)
1755 if ((ochain
[opt
]->sync() || !inc
) && !psf_match
)
1756 d2::image_rw::write_image(ochain_names
[opt
], ochain
[opt
]->get_image());
1759 * Output a summary match statistic.
1762 ui::get()->ale_done((double) d2::align::match_summary());
1765 * Perform any 3D tasks
1768 optimizations::begin_3d_work();
1772 d3::align::init_angle(view_angle
);
1774 d3::align::init_from_d2();
1776 if (d3::cpf::count() > 0) {
1777 d3::cpf::solve_3d();
1780 d3::align::write_alignments();
1782 d3::scene::init_from_d2();
1784 // d3::scene::add_control_points();
1786 // d3::scene::relax_triangle_model();
1788 d3::scene::make_space(d3_depth
, d3_output
, &d3_depth_pt
, &d3_output_pt
);
1790 // fprintf(stderr, "Total pixels: %lu\n", d3::scene::total_pixels);
1791 // fprintf(stderr, "Total ambiguity: %lu\n", d3::scene::total_ambiguity);
1792 // fprintf(stderr, "Total tsteps: %lu\n", d3::scene::total_tsteps);
1793 // fprintf(stderr, "Total divisions: %lu\n", d3::scene::total_divisions);
1795 fprintf(stderr
, "Updating occupancy values");
1796 d3::scene::reduce_cost_to_search_depth(output_exposure
, inc
);
1797 fprintf(stderr
, ".\n");
1799 fprintf(stderr
, "Writing 3D output");
1800 d3::scene::d3px(d3px_count
, d3px_parameters
);
1801 for (unsigned int i
= 0; i
< d2::image_rw::count(); i
++) {
1802 assert (i
< d3_count
);
1804 if (d3_depth
[i
] != NULL
) {
1805 const d2::image
*im
= d3::scene::depth(i
);
1806 d2::image_rw::write_image(d3_depth
[i
], im
, output_exposure
, 1, 1);
1810 if (d3_output
[i
] != NULL
) {
1811 const d2::image
*im
= d3::scene::view(i
);
1812 d2::image_rw::write_image(d3_output
[i
], im
, output_exposure
);
1816 for (std::map
<const char *, d3::pt
>::iterator i
= d3_output_pt
.begin();
1817 i
!= d3_output_pt
.end(); i
++) {
1819 const d2::image
*im
= d3::scene::view(i
->second
);
1820 d2::image_rw::write_image(i
->first
, im
, output_exposure
);
1824 for (std::map
<const char *, d3::pt
>::iterator i
= d3_depth_pt
.begin();
1825 i
!= d3_depth_pt
.end(); i
++) {
1827 const d2::image
*im
= d3::scene::depth(i
->second
);
1828 d2::image_rw::write_image(i
->first
, im
, output_exposure
, 1, 1);
1832 fprintf(stderr
, ".\n");
1834 for (unsigned int i
= d2::image_rw::count(); i
< d3_count
; i
++) {
1835 if (d3_depth
[i
] != NULL
) {
1836 fprintf(stderr
, "\n\n*** Frame number for --3dd too high. ***\n\n");
1838 if (d3_output
[i
] != NULL
) {
1839 fprintf(stderr
, "\n\n*** Frame number for --3dv too high. ***\n\n");
1845 * Destroy the image file handler
1848 d2::image_rw::destroy();
1851 * Delete the transformation file structures, if any
1855 tsave_delete(tsave
);
1856 tload_delete(tload
);
1867 * If there was no output, the user might need more information.