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
= NULL
;
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 * Set default d3chain to default ochain[0].
430 d3chain_type
= ochain_types
[0];
433 * Iterate through arguments until we reach the first file
434 * argument. After the first file argument, we assume that
435 * all following arguments are files.
438 for (int i
= 1; i
< argc
- 1; i
++) {
441 if (!strcmp(argv
[i
], "--q0")
442 || !strcmp(argv
[i
], "--q1")
443 || !strcmp(argv
[i
], "--q2")
444 || !strcmp(argv
[i
], "--qr")
445 || !strcmp(argv
[i
], "--qn")) {
447 * Do nothing. Defaults have already been set.
449 } else if (!strcmp(argv
[i
], "--8bpc")) {
450 d2::image_rw::depth8();
451 } else if (!strcmp(argv
[i
], "--16bpc")) {
452 d2::image_rw::depth16();
453 } else if (!strcmp(argv
[i
], "--plain")) {
454 d2::image_rw::ppm_plain();
455 } else if (!strcmp(argv
[i
], "--raw")) {
456 d2::image_rw::ppm_raw();
457 } else if (!strcmp(argv
[i
], "--auto")) {
458 d2::image_rw::ppm_auto();
459 } else if (!strcmp(argv
[i
], "--align-all")) {
461 } else if (!strcmp(argv
[i
], "--align-green")) {
463 } else if (!strcmp(argv
[i
], "--align-sum")) {
465 } else if (!strcmp(argv
[i
], "--translation")) {
466 d2::align::class_translation();
467 } else if (!strcmp(argv
[i
], "--euclidean")) {
468 d2::align::class_euclidean();
469 } else if (!strcmp(argv
[i
], "--projective")) {
470 d2::align::class_projective();
471 } else if (!strcmp(argv
[i
], "--identity")) {
472 d2::align::initial_default_identity();
473 } else if (!strcmp(argv
[i
], "--follow")) {
474 d2::align::initial_default_follow();
475 } else if (!strcmp(argv
[i
], "--perturb-output")) {
476 d2::align::perturb_output();
477 } else if (!strcmp(argv
[i
], "--perturb-source")) {
478 d2::align::perturb_source();
479 } else if (!strcmp(argv
[i
], "--fail-optimal")) {
480 d2::align::fail_optimal();
481 } else if (!strcmp(argv
[i
], "--fail-default")) {
482 d2::align::fail_default();
483 } else if (!strcmp(argv
[i
], "--no-extend")) {
485 } else if (!strcmp(argv
[i
], "--extend")) {
487 } else if (!strcmp(argv
[i
], "--no-mc")) {
489 } else if (!strcmp(argv
[i
], "--oc")) {
491 } else if (!strcmp(argv
[i
], "--no-oc")) {
493 } else if (!strcmp(argv
[i
], "--gs")) {
497 d2::align::gs(argv
[i
+1]);
500 } else if (!strcmp(argv
[i
], "--gs-mo")) {
502 not_enough("--gs-mo");
504 unsigned int mo_parameter
;
505 if (sscanf(argv
[i
+1], "%u", &mo_parameter
) != 1)
508 d2::align::gs_mo(mo_parameter
);
511 } else if (!strcmp(argv
[i
], "--focus")) {
514 * Check for argument availability
521 double sd
, ed
, fd
, cc
, df
, vt
, ht
;
523 if (sscanf(argv
[i
+1], "%u", &ci
) != 1
524 || sscanf(argv
[i
+2], "%lf", &sd
) != 1
525 || sscanf(argv
[i
+3], "%lf", &ed
) != 1
526 || sscanf(argv
[i
+4], "%lf", &fd
) != 1
527 || sscanf(argv
[i
+5], "%lf", &cc
) != 1
528 || sscanf(argv
[i
+6], "%lf", &df
) != 1
529 || sscanf(argv
[i
+7], "%lf", &vt
) != 1
530 || sscanf(argv
[i
+8], "%lf", &ht
) != 1)
533 d3::focus::add_region(ci
, sd
, ed
, fd
, cc
, df
, vt
, ht
);
536 } else if (!strcmp(argv
[i
], "--3ddp") || !strcmp(argv
[i
], "--3dvp")) {
540 * Unsupported configurations
544 unsupported::fornow("3D modeling with Irani-Peleg rendering");
548 unsupported::fornow("3D modeling with unsharp mask");
552 * Check for argument availability
559 * Initialize if necessary
561 * Note: because their existence is checked as an
562 * indicator of the presence of 3D arguments, we
563 * initialize these structures here.
566 if (d3_output
== NULL
) {
567 d3_count
= argc
- (i
+ 2) - 1;
568 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
569 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
572 unsigned int width
, height
;
577 if (sscanf(argv
[i
+1], "%u", &width
) != 1
578 || sscanf(argv
[i
+2], "%u", &height
) != 1
579 || sscanf(argv
[i
+3], "%lf", &view_angle
) != 1
580 || sscanf(argv
[i
+4], "%lf", &x
) != 1
581 || sscanf(argv
[i
+5], "%lf", &y
) != 1
582 || sscanf(argv
[i
+6], "%lf", &z
) != 1
583 || sscanf(argv
[i
+7], "%lf", &P
) != 1
584 || sscanf(argv
[i
+8], "%lf", &Y
) != 1
585 || sscanf(argv
[i
+9], "%lf", &R
) != 1)
588 view_angle
*= M_PI
/ 180;
593 d2::transformation t
=
594 d2::transformation::eu_identity();
595 t
.set_domain(height
, width
);
596 d3::pt
_pt(t
, d3::et(y
, x
, z
, Y
, P
, R
), view_angle
);
598 if (!strcmp(argv
[i
], "--3dvp")) {
599 d3_output_pt
[argv
[i
+10]] = _pt
;
600 } else if (!strcmp(argv
[i
], "--3ddp")) {
601 d3_depth_pt
[argv
[i
+10]] = _pt
;
607 } else if (!strcmp(argv
[i
], "--3dv")) {
610 unsigned int frame_no
;
613 * Unsupported configurations
617 unsupported::fornow("3D modeling with Irani-Peleg rendering");
621 unsupported::fornow("3D modeling with unsharp mask");
625 * Check for argument availability
632 * Initialize if necessary
635 if (d3_output
== NULL
) {
636 d3_count
= argc
- (i
+ 2) - 1;
637 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
638 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
641 if (sscanf(argv
[i
+1], "%d", &frame_no
) != 1)
642 ui::get()->error("--3dv argument 0 must be an integer");
644 if (frame_no
>= d3_count
)
645 ui::get()->error("--3dv argument 0 is too large");
647 if (d3_output
[frame_no
] != NULL
) {
648 unsupported::fornow ("Writing a single 3D view to more than one output file");
651 d3_output
[frame_no
] = argv
[i
+2];
654 } else if (!strcmp(argv
[i
], "--3dd")) {
657 unsigned int frame_no
;
660 * Unsupported configurations
664 unsupported::fornow("3D modeling with Irani-Peleg rendering");
668 unsupported::fornow("3D modeling with unsharp mask");
672 * Check for argument availability
679 * Initialize if necessary
682 if (d3_output
== NULL
) {
683 d3_count
= argc
- (i
+ 2) - 1;
684 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
685 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
688 if (sscanf(argv
[i
+1], "%d", &frame_no
) != 1)
689 ui::get()->error("--3dd argument 0 must be an integer");
691 if (frame_no
>= d3_count
)
692 ui::get()->error("--3dd argument 0 is too large");
694 if (d3_depth
[frame_no
] != NULL
) {
695 unsupported::fornow ("Writing a single frame's depth info to more than one output file");
698 d3_depth
[frame_no
] = argv
[i
+2];
702 } else if (!strcmp(argv
[i
], "--view-angle")) {
704 not_enough("--view-angle");
707 sscanf(argv
[i
+1], "%lf", &va_parameter
);
709 user_view_angle
= va_parameter
* M_PI
/ 180;
710 } else if (!strcmp(argv
[i
], "--cpf-load")) {
712 not_enough("--cpf-load");
714 d3::cpf::init_loadfile(argv
[i
+1]);
716 } else if (!strcmp(argv
[i
], "--ui=stream")) {
718 } else if (!strcmp(argv
[i
], "--ui=tty")) {
720 } else if (!strcmp(argv
[i
], "--3d-fmr")) {
723 not_enough("--3d-fmr");
725 double fmr_parameter
;
726 sscanf(argv
[i
+1], "%lf", &fmr_parameter
);
728 d3::scene::fmr(fmr_parameter
);
730 } else if (!strcmp(argv
[i
], "--3d-dmr")) {
733 not_enough("--3d-dmr");
735 double dmr_parameter
;
736 sscanf(argv
[i
+1], "%lf", &dmr_parameter
);
738 d3::scene::dmr(dmr_parameter
);
740 } else if (!strcmp(argv
[i
], "--et")) {
746 sscanf(argv
[i
+1], "%lf", &et_parameter
);
748 d3::scene::et(et_parameter
);
750 } else if (!strcmp(argv
[i
], "--st")) {
755 sscanf(argv
[i
+1], "%lf", &st_parameter
);
757 d3::cpf::st(st_parameter
);
758 } else if (!strcmp(argv
[i
], "--di-lower")) {
760 not_enough("--di-lower");
763 sscanf(argv
[i
+1], "%lf", &di_parameter
);
765 d3::scene::di_lower(di_parameter
);
766 } else if (!strcmp(argv
[i
], "--rc")) {
771 sscanf(argv
[i
+1], "%lf", &rc_parameter
);
773 d3::scene::rc(rc_parameter
);
774 } else if (!strcmp(argv
[i
], "--do-try")) {
776 not_enough("--do-try");
779 sscanf(argv
[i
+1], "%lf", &do_parameter
);
781 d3::scene::do_try(do_parameter
);
782 } else if (!strcmp(argv
[i
], "--di-upper")) {
784 not_enough("--di-upper");
786 double dgi_parameter
;
787 sscanf(argv
[i
+1], "%lf", &dgi_parameter
);
789 d3::scene::di_upper(dgi_parameter
);
790 } else if (!strcmp(argv
[i
], "--fc")) {
795 sscanf(argv
[i
+1], "%lf", &fc_parameter
);
797 d3::scene::fc(fc_parameter
);
798 } else if (!strcmp(argv
[i
], "--ecm")) {
799 unsupported::discontinued("--ecm <x>");
800 } else if (!strcmp(argv
[i
], "--acm")) {
801 unsupported::discontinued("--acm <x>");
802 } else if (!strcmp(argv
[i
], "--def-nn")) {
804 not_enough("--def-nn");
807 sscanf(argv
[i
+1], "%lf", &nn_parameter
);
809 d2::image_rw::def_nn(nn_parameter
);
811 if (nn_parameter
> 2) {
812 fprintf(stderr
, "\n\n*** Warning: --def-nn implementation is currently "
813 "inefficient for large radii. ***\n\n");
816 } else if (!strcmp(argv
[i
], "--mc")) {
821 sscanf(argv
[i
+1], "%lf", &mc_parameter
);
824 d2::align::mc(mc_parameter
);
826 } else if (!strcmp(argv
[i
], "--fx")) {
832 sscanf(argv
[i
+1], "%lf", &fx_parameter
);
834 d3::scene::fx(fx_parameter
);
836 } else if (!strcmp(argv
[i
], "--tcem")) {
839 not_enough("--tcem");
841 double tcem_parameter
;
842 sscanf(argv
[i
+1], "%lf", &tcem_parameter
);
844 d3::scene::tcem(tcem_parameter
);
846 } else if (!strcmp(argv
[i
], "--oui")) {
851 unsigned int oui_parameter
;
852 sscanf(argv
[i
+1], "%u", &oui_parameter
);
854 d3::scene::oui(oui_parameter
);
856 } else if (!strcmp(argv
[i
], "--pa")) {
861 unsigned int pa_parameter
;
862 sscanf(argv
[i
+1], "%u", &pa_parameter
);
864 d3::scene::pa(pa_parameter
);
866 } else if (!strcmp(argv
[i
], "--pc")) {
871 d3::scene::pc(argv
[i
+1]);
874 } else if (!strcmp(argv
[i
], "--cw")) {
875 d2::align::certainty_weighted(1);
876 } else if (!strcmp(argv
[i
], "--no-cw")) {
877 d2::align::certainty_weighted(0);
878 } else if (!strcmp(argv
[i
], "--wm")) {
879 if (wm_filename
!= NULL
)
880 ui::get()->error("only one weight map can be specified");
884 wm_filename
= argv
[i
+1];
886 if (sscanf(argv
[i
+2], "%d", &wm_offsetx
) != 1)
887 ui::get()->error("--wm x-argument must be an integer");
889 if (sscanf(argv
[i
+3], "%d", &wm_offsety
) != 1)
890 ui::get()->error("--wm y-argument must be an integer");
894 } else if (!strcmp(argv
[i
], "--fl")) {
898 if (sscanf(argv
[i
+1], "%lf", &h
) != 1)
899 ui::get()->error("--fl h-argument must be numerical");
900 if (sscanf(argv
[i
+2], "%lf", &v
) != 1)
901 ui::get()->error("--fl v-argument must be numerical");
902 if (sscanf(argv
[i
+3], "%lf", &a
) != 1)
903 ui::get()->error("--fl a-argument must be numerical");
906 d2::align::set_frequency_cut(h
, v
, a
);
908 ui::get()->error_hint("--fl is not supported", "rebuild ALE with FFTW=1");
910 } else if (!strcmp(argv
[i
], "--wmx")) {
914 d2::align::set_wmx(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
916 ui::get()->error_hint("--wmx is not supported", "rebuild ALE with POSIX=1");
919 } else if (!strcmp(argv
[i
], "--flshow")) {
921 not_enough("--flshow");
922 d2::align::set_fl_show(argv
[i
+1]);
924 } else if (!strcmp(argv
[i
], "--3dpx")) {
926 not_enough("--3dpx");
928 d3px_parameters
= (double *) local_realloc(d3px_parameters
, (d3px_count
+ 1) * 6 * sizeof(double));
930 for (int param
= 0; param
< 6; param
++)
931 if (sscanf(argv
[i
+ param
+ 1], "%lf", &(d3px_parameters
[6 * d3px_count
+ param
])) != 1)
935 * Swap x and y, since their internal meanings differ from their external meanings.
938 for (int param
= 0; param
< 2; param
++) {
939 double temp
= d3px_parameters
[6 * d3px_count
+ 2 + param
];
940 d3px_parameters
[6 * d3px_count
+ 2 + param
] = d3px_parameters
[6 * d3px_count
+ 0 + param
];
941 d3px_parameters
[6 * d3px_count
+ 0 + param
] = temp
;
951 } else if (!strcmp(argv
[i
], "--ex")) {
955 ex_parameters
= (int *) local_realloc(ex_parameters
, (ex_count
+ 1) * 6 * sizeof(int));
957 for (int param
= 0; param
< 6; param
++)
958 if (sscanf(argv
[i
+ param
+ 1], "%d", &(ex_parameters
[6 * ex_count
+ param
])) != 1)
962 * Swap x and y, since their internal meanings differ from their external meanings.
965 for (int param
= 0; param
< 2; param
++) {
966 int temp
= ex_parameters
[6 * ex_count
+ 2 + param
];
967 ex_parameters
[6 * ex_count
+ 2 + param
] = ex_parameters
[6 * ex_count
+ 0 + param
];
968 ex_parameters
[6 * ex_count
+ 0 + param
] = temp
;
978 } else if (!strcmp(argv
[i
], "--crop")) {
980 not_enough("--crop");
982 ex_parameters
= (int *) local_realloc(ex_parameters
, (ex_count
+ 4) * 6 * sizeof(int));
985 for (int param
= 0; param
< 6; param
++)
986 if (sscanf(argv
[i
+ param
+ 1], "%d", &(crop_args
[param
])) != 1)
990 * Construct exclusion regions from the crop area,
991 * swapping x and y, since their internal meanings
992 * differ from their external meanings.
996 * Exclusion region 1: low x
999 ex_parameters
[6 * ex_count
+ 0] = INT_MIN
;
1000 ex_parameters
[6 * ex_count
+ 1] = crop_args
[2] - 1;
1001 ex_parameters
[6 * ex_count
+ 2] = INT_MIN
;
1002 ex_parameters
[6 * ex_count
+ 3] = INT_MAX
;
1003 ex_parameters
[6 * ex_count
+ 4] = crop_args
[4];
1004 ex_parameters
[6 * ex_count
+ 5] = crop_args
[5];
1007 * Exclusion region 2: low y
1010 ex_parameters
[6 * ex_count
+ 6] = INT_MIN
;
1011 ex_parameters
[6 * ex_count
+ 7] = INT_MAX
;
1012 ex_parameters
[6 * ex_count
+ 8] = INT_MIN
;
1013 ex_parameters
[6 * ex_count
+ 9] = crop_args
[0] - 1;
1014 ex_parameters
[6 * ex_count
+ 10] = crop_args
[4];
1015 ex_parameters
[6 * ex_count
+ 11] = crop_args
[5];
1018 * Exclusion region 3: high y
1021 ex_parameters
[6 * ex_count
+ 12] = INT_MIN
;
1022 ex_parameters
[6 * ex_count
+ 13] = INT_MAX
;
1023 ex_parameters
[6 * ex_count
+ 14] = crop_args
[1] + 1;
1024 ex_parameters
[6 * ex_count
+ 15] = INT_MAX
;
1025 ex_parameters
[6 * ex_count
+ 16] = crop_args
[4];
1026 ex_parameters
[6 * ex_count
+ 17] = crop_args
[5];
1029 * Exclusion region 4: high x
1032 ex_parameters
[6 * ex_count
+ 18] = crop_args
[3] + 1;
1033 ex_parameters
[6 * ex_count
+ 19] = INT_MAX
;
1034 ex_parameters
[6 * ex_count
+ 20] = INT_MIN
;
1035 ex_parameters
[6 * ex_count
+ 21] = INT_MAX
;
1036 ex_parameters
[6 * ex_count
+ 22] = crop_args
[4];
1037 ex_parameters
[6 * ex_count
+ 23] = crop_args
[5];
1040 * Increment counters
1045 } else if (!strcmp(argv
[i
], "--exshow")) {
1047 } else if (!strcmp(argv
[i
], "--wt")) {
1053 if (sscanf(argv
[i
+ 1], "%lf", &wt
) != 1)
1056 d2::render::set_wt(wt
);
1058 } else if (!strcmp(argv
[i
], "--3d-chain")) {
1060 not_enough("--3d-chain");
1061 d3chain_type
= argv
[i
+1];
1063 } else if (!strcmp(argv
[i
], "--dchain")) {
1065 not_enough("--dchain");
1066 ochain_types
[0] = argv
[i
+1];
1068 } else if (!strcmp(argv
[i
], "--achain")) {
1070 not_enough("--achain");
1071 achain_type
= argv
[i
+1];
1073 } else if (!strcmp(argv
[i
], "--afilter")) {
1075 not_enough("--afilter");
1076 afilter_type
= argv
[i
+1];
1078 } else if (!strcmp(argv
[i
], "--ochain")) {
1080 not_enough("--ochain");
1082 ochain
= (d2::render
**) local_realloc(ochain
,
1083 (oc_count
+ 1) * sizeof(d2::render
*));
1084 ochain_names
= (const char **) local_realloc((void *)ochain_names
,
1085 (oc_count
+ 1) * sizeof(const char *));
1086 ochain_types
= (const char **) local_realloc((void *)ochain_types
,
1087 (oc_count
+ 1) * sizeof(const char *));
1089 ochain_types
[oc_count
] = argv
[i
+1];
1090 ochain_names
[oc_count
] = argv
[i
+2];
1094 } else if (!strcmp(argv
[i
], "--visp")) {
1096 not_enough("--visp");
1098 visp
= (const char **) local_realloc((void *)visp
, 4 *
1099 (vise_count
+ 1) * sizeof(const char *));
1101 for (int param
= 0; param
< 4; param
++)
1102 visp
[vise_count
* 4 + param
] = argv
[i
+ 1 + param
];
1106 } else if (!strcmp(argv
[i
], "--cx")) {
1111 sscanf(argv
[i
+1], "%lf", &cx_parameter
);
1114 } else if (!strcmp(argv
[i
], "--no-cx")) {
1116 } else if (!strcmp(argv
[i
], "--ip")) {
1117 unsupported::discontinued("--ip <r> <i>", "--lpsf box=<r> --ips <i>");
1118 } else if (!strcmp(argv
[i
], "--bayer")) {
1120 not_enough("--bayer");
1123 * External order is clockwise from top-left. Internal
1124 * order is counter-clockwise from top-left.
1127 if (!strcmp(argv
[i
+1], "rgbg")) {
1128 user_bayer
= IMAGE_BAYER_RGBG
;
1129 } else if (!strcmp(argv
[i
+1], "bgrg")) {
1130 user_bayer
= IMAGE_BAYER_BGRG
;
1131 } else if (!strcmp(argv
[i
+1], "gbgr")) {
1132 user_bayer
= IMAGE_BAYER_GRGB
;
1133 } else if (!strcmp(argv
[i
+1], "grgb")) {
1134 user_bayer
= IMAGE_BAYER_GBGR
;
1135 } else if (!strcmp(argv
[i
+1], "none")) {
1136 user_bayer
= IMAGE_BAYER_NONE
;
1141 } else if (!strcmp(argv
[i
], "--lpsf")) {
1143 not_enough("--lpsf");
1145 psf
[psf_linear
] = argv
[i
+1];
1147 } else if (!strcmp(argv
[i
], "--nlpsf")) {
1149 not_enough("--nlpsf");
1151 psf
[psf_nonlinear
] = argv
[i
+1];
1154 } else if (!strcmp(argv
[i
], "--psf-match")) {
1156 not_enough("--psf-match");
1160 for (int index
= 0; index
< 6; index
++) {
1161 if (sscanf(argv
[i
+ 1], "%lf", &psf_match_args
[index
]) != 1)
1162 bad_arg("--psf-match");
1166 } else if (!strcmp(argv
[i
], "--device")) {
1168 not_enough("--device");
1174 } else if (!strcmp(argv
[i
], "--usm")) {
1176 if (d3_output
!= NULL
)
1177 unsupported::fornow("3D modeling with unsharp mask");
1180 not_enough("--usm");
1182 sscanf(argv
[i
+1], "%lf", &usm_multiplier
);
1186 } else if (!strcmp(argv
[i
], "--ipr")) {
1189 not_enough("--ipr");
1191 if (sscanf(argv
[i
+1], "%d", &ip_iterations
) != 1)
1192 ui::get()->error("--ipr requires an integer argument");
1194 ui::get()->warn("--ipr is deprecated. Use --ips instead");
1197 } else if (!strcmp(argv
[i
], "--cpp-err-median")) {
1198 d3::cpf::err_median();
1199 } else if (!strcmp(argv
[i
], "--cpp-err-mean")) {
1200 d3::cpf::err_mean();
1201 } else if (!strcmp(argv
[i
], "--vp-adjust")) {
1202 d3::align::vp_adjust();
1203 } else if (!strcmp(argv
[i
], "--vp-noadjust")) {
1204 d3::align::vp_noadjust();
1205 } else if (!strcmp(argv
[i
], "--vo-adjust")) {
1206 d3::align::vo_adjust();
1207 } else if (!strcmp(argv
[i
], "--vo-noadjust")) {
1208 d3::align::vo_noadjust();
1209 } else if (!strcmp(argv
[i
], "--ip-mean")) {
1211 } else if (!strcmp(argv
[i
], "--ip-median")) {
1213 } else if (!strcmp(argv
[i
], "--ips")) {
1216 not_enough("--ips");
1218 if (sscanf(argv
[i
+1], "%d", &ip_iterations
) != 1)
1219 ui::get()->error("--ips requires an integer argument");
1221 } else if (!strcmp(argv
[i
], "--ipc")) {
1222 unsupported::discontinued("--ipc <c> <i>", "--ips <i> --lpsf <c>", "--ips <i> --device <c>");
1223 } else if (!strcmp(argv
[i
], "--exp-extend")) {
1224 d2::image_rw::exp_scale();
1225 } else if (!strcmp(argv
[i
], "--exp-noextend")) {
1226 d2::image_rw::exp_noscale();
1227 } else if (!strcmp(argv
[i
], "--exp-register")) {
1228 exposure_register
= 1;
1229 d2::align::exp_register();
1230 } else if (!strcmp(argv
[i
], "--exp-noregister")) {
1231 exposure_register
= 0;
1232 d2::align::exp_noregister();
1233 } else if (!strcmp(argv
[i
], "--exp-meta-only")) {
1234 exposure_register
= 2;
1235 d2::align::exp_meta_only();
1236 } else if (!strcmp(argv
[i
], "--drizzle-only")) {
1237 unsupported::discontinued("--drizzle-only", "--dchain box:1");
1238 } else if (!strcmp(argv
[i
], "--subspace-traverse")) {
1239 unsupported::undocumented("--subspace-traverse");
1240 d3::scene::set_subspace_traverse();
1241 } else if (!strcmp(argv
[i
], "--3d-nofilter")) {
1242 d3::scene::filter();
1243 } else if (!strcmp(argv
[i
], "--3d-filter")) {
1244 d3::scene::nofilter();
1245 } else if (!strcmp(argv
[i
], "--occ-norm")) {
1247 } else if (!strcmp(argv
[i
], "--occ-nonorm")) {
1249 } else if (!strcmp(argv
[i
], "--inc")) {
1251 } else if (!strcmp(argv
[i
], "--no-inc")) {
1253 } else if (!strncmp(argv
[i
], "--exp-mult=", strlen("--exp-mult="))) {
1254 double exp_c
, exp_r
, exp_b
;
1255 sscanf(argv
[i
] + strlen("--exp-mult="), "%lf,%lf,%lf", &exp_c
, &exp_r
, &exp_b
);
1256 exp_mult
= d2::pixel(1/(exp_r
* exp_c
), 1/exp_c
, 1/(exp_b
* exp_c
));
1257 } else if (!strncmp(argv
[i
], "--visp-scale=", strlen("--visp-scale="))) {
1259 sscanf(argv
[i
] + strlen("--visp-scale="), "%lf", &vise_scale_factor
);
1261 if (vise_scale_factor
<= 0.0)
1262 ui::get()->error("VISP scale must be greater than zero");
1264 if (!finite(vise_scale_factor
))
1265 ui::get()->error("VISP scale must be finite");
1267 } else if (!strncmp(argv
[i
], "--scale=", strlen("--scale="))) {
1269 sscanf(argv
[i
] + strlen("--scale="), "%lf", &scale_factor
);
1271 if (scale_factor
<= 0)
1272 ui::get()->error("Scale factor must be greater than zero");
1274 if (!finite(scale_factor
))
1275 ui::get()->error("Scale factor must be finite");
1277 } else if (!strncmp(argv
[i
], "--metric=", strlen("--metric="))) {
1279 sscanf(argv
[i
] + strlen("--metric="), "%lf", &metric
);
1280 d2::align::set_metric_exponent(metric
);
1281 } else if (!strncmp(argv
[i
], "--threshold=", strlen("--threshold="))) {
1282 double match_threshold
;
1283 sscanf(argv
[i
] + strlen("--threshold="), "%lf", &match_threshold
);
1284 d2::align::set_match_threshold(match_threshold
);
1285 } else if (!strncmp(argv
[i
], "--drizzle-diam=", strlen("--drizzle-diam="))) {
1286 unsupported::discontinued("--drizzle-diam=<x>", "--dchain box:1");
1287 // sscanf(argv[i] + strlen("--drizzle-diam="), "%lf", &drizzle_radius);
1288 // drizzle_radius /= 2;
1289 } else if (!strncmp(argv
[i
], "--perturb-upper=", strlen("--perturb-upper="))) {
1290 double perturb_upper
;
1292 sscanf(argv
[i
] + strlen("--perturb-upper="), "%lf%n", &perturb_upper
,
1294 if (*(argv
[i
] + strlen("--perturb-upper=") + characters
) == '%')
1295 d2::align::set_perturb_upper(perturb_upper
, 1);
1297 d2::align::set_perturb_upper(perturb_upper
, 0);
1298 } else if (!strncmp(argv
[i
], "--perturb-lower=", strlen("--perturb-lower="))) {
1299 double perturb_lower
;
1301 sscanf(argv
[i
] + strlen("--perturb-lower="), "%lf%n", &perturb_lower
,
1303 if (perturb_lower
<= 0)
1304 ui::get()->error("--perturb-lower= value is non-positive");
1306 if (*(argv
[i
] + strlen("--perturb-lower=") + characters
) == '%')
1307 d2::align::set_perturb_lower(perturb_lower
, 1);
1309 d2::align::set_perturb_lower(perturb_lower
, 0);
1310 } else if (!strncmp(argv
[i
], "--stepsize=", strlen("--stepsize="))) {
1311 double perturb_lower
;
1312 ui::get()->warn("--stepsize is deprecated. Use --perturb-lower instead");
1313 sscanf(argv
[i
] + strlen("--stepsize="), "%lf", &perturb_lower
);
1314 d2::align::set_perturb_lower(perturb_lower
, 0);
1315 } else if (!strncmp(argv
[i
], "--va-upper=", strlen("--va-upper="))) {
1318 sscanf(argv
[i
] + strlen("--va-upper="), "%lf%n", &va_upper
,
1320 if (*(argv
[i
] + strlen("--va-upper=") + characters
) == '%')
1321 ui::get()->error("--va-upper= does not accept '%' arguments\n");
1323 d3::cpf::set_va_upper(va_upper
);
1324 } else if (!strncmp(argv
[i
], "--cpp-upper=", strlen("--cpp-upper="))) {
1325 double perturb_upper
;
1327 sscanf(argv
[i
] + strlen("--cpp-upper="), "%lf%n", &perturb_upper
,
1329 if (*(argv
[i
] + strlen("--cpp-upper=") + characters
) == '%')
1330 ui::get()->error("--cpp-upper= does not currently accept '%' arguments\n");
1332 d3::cpf::set_cpp_upper(perturb_upper
);
1333 } else if (!strncmp(argv
[i
], "--cpp-lower=", strlen("--cpp-lower="))) {
1334 double perturb_lower
;
1336 sscanf(argv
[i
] + strlen("--cpp-lower="), "%lf%n", &perturb_lower
,
1338 if (*(argv
[i
] + strlen("--cpp-lower=") + characters
) == '%')
1339 ui::get()->error("--cpp-lower= does not currently accept '%' arguments\n");
1341 d3::cpf::set_cpp_lower(perturb_lower
);
1342 } else if (!strncmp(argv
[i
], "--hf-enhance=", strlen("--hf-enhance="))) {
1343 unsupported::discontinued("--hf-enhance=<x>");
1344 } else if (!strncmp(argv
[i
], "--rot-upper=", strlen("--rot-upper="))) {
1346 sscanf(argv
[i
] + strlen("--rot-upper="), "%lf", &rot_max
);
1347 d2::align::set_rot_max((int) floor(rot_max
));
1348 } else if (!strncmp(argv
[i
], "--bda-mult=", strlen("--bda-mult="))) {
1350 sscanf(argv
[i
] + strlen("--bda-mult="), "%lf", &bda_mult
);
1351 d2::align::set_bda_mult(bda_mult
);
1352 } else if (!strncmp(argv
[i
], "--bda-rate=", strlen("--bda-rate="))) {
1354 sscanf(argv
[i
] + strlen("--bda-rate="), "%lf", &bda_rate
);
1355 d2::align::set_bda_rate(bda_rate
);
1356 } else if (!strncmp(argv
[i
], "--lod-max=", strlen("--lod-max="))) {
1358 sscanf(argv
[i
] + strlen("--lod-max="), "%lf", &lod_max
);
1359 d2::align::set_lod_max((int) floor(lod_max
));
1360 } else if (!strncmp(argv
[i
], "--cpf-load=", strlen("--cpf-load="))) {
1361 d3::cpf::init_loadfile(argv
[i
] + strlen("--cpf-load="));
1363 } else if (!strncmp(argv
[i
], "--model-load=", strlen("--model-load="))) {
1364 d3::scene::load_model(argv
[i
] + strlen("--model-load="));
1365 } else if (!strncmp(argv
[i
], "--model-save=", strlen("--model-save="))) {
1366 d3::scene::save_model(argv
[i
] + strlen("--model-save="));
1368 } else if (!strncmp(argv
[i
], "--trans-load=", strlen("--trans-load="))) {
1369 d2::tload_delete(tload
);
1370 tload
= d2::tload_new(argv
[i
] + strlen("--trans-load="));
1371 d2::align::set_tload(tload
);
1372 } else if (!strncmp(argv
[i
], "--trans-save=", strlen("--trans-save="))) {
1373 tsave_delete(tsave
);
1374 tsave
= d2::tsave_new(argv
[i
] + strlen("--trans-save="));
1375 d2::align::set_tsave(tsave
);
1376 } else if (!strncmp(argv
[i
], "--3d-trans-load=", strlen("--3d-trans-load="))) {
1377 d3::tload_delete(d3_tload
);
1378 d3_tload
= d3::tload_new(argv
[i
] + strlen("--3d-trans-load="));
1379 d3::align::set_tload(d3_tload
);
1380 } else if (!strncmp(argv
[i
], "--3d-trans-save=", strlen("--3d-trans-save="))) {
1381 d3::tsave_delete(d3_tsave
);
1382 d3_tsave
= d3::tsave_new(argv
[i
] + strlen("--3d-trans-save="));
1383 d3::align::set_tsave(d3_tsave
);
1387 * Trap illegal options and end-of-option indicators.
1390 if (!strcmp(argv
[i
], "--"))
1392 else if (!strncmp(argv
[i
], "--", strlen("--")))
1393 ui::get()->illegal_option(argv
[i
]);
1396 * Apply implication logic.
1399 if (extend
== 0 && vise_count
!= 0) {
1400 implication::changed("VISP requires increased image extents.",
1401 "Image extension is now enabled.",
1406 if (psf_match
&& ex_count
)
1407 unsupported::fornow("PSF calibration with exclusion regions.");
1410 if (d3_output
!= NULL
&& ip_iterations
!= 0)
1411 unsupported::fornow("3D modeling with Irani-Peleg rendering");
1414 if (extend
== 0 && d3_output
!= NULL
) {
1415 implication::changed("3D modeling requires increased image extents.",
1416 "Image extension is now enabled.",
1422 if (cx_parameter
!= 0 && !exposure_register
) {
1423 implication::changed("Certainty-based rendering requires exposure registration.",
1424 "Exposure registration is now enabled.",
1426 d2::align::exp_register();
1427 exposure_register
= 1;
1431 * Set alignment class exclusion region static variables
1434 d2::align::set_exclusion(ex_parameters
, ex_count
);
1437 * Initialize renderer class statics.
1440 d2::render::render_init(ex_count
, ex_parameters
, ex_show
, extend
, scale_factor
);
1446 d2::exposure::set_confidence(cx_parameter
);
1449 * Keep transformations for Irani-Peleg, psf-match, and
1453 if (ip_iterations
> 0 || psf_match
|| vise_count
> 0) {
1458 * Initialize device-specific variables
1461 d2::psf
*device_response
[psf_N
] = { NULL
, NULL
};
1462 d2::exposure
**input_exposure
= NULL
;
1463 ale_pos view_angle
= 43.7 * M_PI
/ 180;
1464 // ale_pos view_angle = 90 * M_PI / 180;
1465 input_exposure
= (d2::exposure
**)
1466 malloc((argc
- i
- 1) * sizeof(d2::exposure
*));
1468 if (device
!= NULL
) {
1469 if (!strcmp(device
, "xvp610_640x480")) {
1470 device_response
[psf_linear
] = new xvp610_640x480::lpsf();
1471 device_response
[psf_nonlinear
] = new xvp610_640x480::nlpsf();
1472 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1473 input_exposure
[ii
] = new xvp610_640x480::exposure();
1474 view_angle
= xvp610_640x480::view_angle();
1475 } else if (!strcmp(device
, "xvp610_320x240")) {
1476 device_response
[psf_linear
] = new xvp610_320x240::lpsf();
1477 device_response
[psf_nonlinear
] = new xvp610_320x240::nlpsf();
1478 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1479 input_exposure
[ii
] = new xvp610_320x240::exposure();
1480 view_angle
= xvp610_320x240::view_angle();
1481 } else if (!strcmp(device
, "ov7620_raw_linear")) {
1482 device_response
[psf_linear
] = new ov7620_raw_linear::lpsf();
1483 device_response
[psf_nonlinear
] = NULL
;
1484 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1485 input_exposure
[ii
] = new ov7620_raw_linear::exposure();
1486 d2::image_rw::set_default_bayer(IMAGE_BAYER_BGRG
);
1487 } else if (!strcmp(device
, "canon_300d_raw_linear")) {
1488 device_response
[psf_linear
] = new canon_300d_raw_linear::lpsf();
1489 device_response
[psf_nonlinear
] = NULL
;
1490 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1491 input_exposure
[ii
] = new canon_300d_raw_linear::exposure();
1492 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1493 } else if (!strcmp(device
, "canon_300d_raw_linear+85mm_1.8")) {
1494 device_response
[psf_linear
] = new canon_300d_raw_linear_85mm_1_8::lpsf();
1495 device_response
[psf_nonlinear
] = NULL
;
1496 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1497 input_exposure
[ii
] = new canon_300d_raw_linear_85mm_1_8::exposure();
1498 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1499 view_angle
= canon_300d_raw_linear_85mm_1_8::view_angle();
1500 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.8")) {
1501 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_8::lpsf();
1502 device_response
[psf_nonlinear
] = NULL
;
1503 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1504 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_8::exposure();
1505 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1506 view_angle
= canon_300d_raw_linear_50mm_1_8::view_angle();
1507 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.4")) {
1508 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_4::lpsf();
1509 device_response
[psf_nonlinear
] = NULL
;
1510 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1511 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_4::exposure();
1512 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1513 view_angle
= canon_300d_raw_linear_50mm_1_4::view_angle();
1514 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.4@1.4")) {
1515 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_4_1_4::lpsf();
1516 device_response
[psf_nonlinear
] = NULL
;
1517 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1518 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_4_1_4::exposure();
1519 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1520 view_angle
= canon_300d_raw_linear_50mm_1_4_1_4::view_angle();
1522 ui::get()->unknown_device(device
);
1525 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1526 input_exposure
[ii
] = new d2::exposure_default();
1530 * User-specified variables.
1533 if (user_view_angle
!= 0) {
1534 view_angle
= user_view_angle
;
1537 if (user_bayer
!= IMAGE_BAYER_DEFAULT
) {
1538 d2::image_rw::set_default_bayer(user_bayer
);
1542 * PSF-match exposure.
1545 delete input_exposure
[argc
- i
- 2];
1546 input_exposure
[argc
- i
- 2] = new d2::exposure_default();
1550 * Initialize output exposure
1553 d2::exposure
*output_exposure
= new d2::exposure_default();
1554 output_exposure
->set_multiplier(exp_mult
);
1557 * Configure the response function.
1560 d2::psf
*response
[2] = {NULL
, NULL
};
1562 for (int n
= 0; n
< psf_N
; n
++ ) {
1563 if (psf
[n
] != NULL
) {
1565 response
[n
] = d2::psf_parse::get((n
== psf_linear
), psf
[n
]);
1567 } else if (device_response
[n
] != NULL
) {
1570 * Device-specific response
1573 response
[n
] = device_response
[n
];
1578 * Default point-spread function.
1581 if (n
== psf_linear
) {
1584 * Default lpsf is a box filter
1585 * of diameter 1.0 (radius
1589 response
[n
] = new d2::box(0.5);
1591 } else if (n
== psf_nonlinear
) {
1594 * nlpsf is disabled by default.
1603 * First file argument. Print general file information as well
1604 * as information specific to this argument. Initialize image
1609 * There should be at least two file arguments.
1612 if (i
>= argc
- 1) {
1617 d2::image_rw::init(argc
- i
- 1, argv
+ i
, argv
[argc
- 1], input_exposure
, output_exposure
);
1618 ochain_names
[0] = argv
[argc
- 1];
1621 * Handle control point data for alignment
1623 d2::align::set_cp_count(d3::cpf::count());
1624 for (unsigned int ii
= 0; ii
< d3::cpf::count(); ii
++)
1625 d2::align::set_cp(ii
, d3::cpf::get_2d(ii
));
1628 * PSF-match bayer patterns.
1632 d2::image_rw::set_specific_bayer(argc
- i
- 2, IMAGE_BAYER_NONE
);
1636 * Handle alignment weight map, if necessary
1639 if (wm_filename
!= NULL
) {
1640 d2::image
*weight_map
;
1641 weight_map
= d2::image_rw::read_image(wm_filename
, new d2::exposure_linear());
1642 weight_map
->set_offset(wm_offsety
, wm_offsetx
);
1643 d2::align::set_weight_map(weight_map
);
1647 * Write comment information about original frame and
1648 * target image to the transformation save file, if we
1652 const d2::image
*im
= d2::image_rw::open(0);
1653 tsave_orig(tsave
, argv
[i
], im
->avg_channel_magnitude());
1654 tsave_target(tsave
, argv
[argc
- 1]);
1655 d2::image_rw::close(0);
1658 * Initialize alignment interpolant.
1661 if (afilter_type
!= "internal")
1662 d2::align::set_interpolant(d2::render_parse::get_SSF(afilter_type
));
1665 * Initialize achain and ochain.
1668 achain
= d2::render_parse::get(achain_type
);
1670 for (int chain
= 0; chain
< oc_count
; chain
++)
1671 ochain
[chain
] = d2::render_parse::get(ochain_types
[chain
]);
1674 * Use merged renderings as reference images in
1678 d2::align::set_reference(achain
);
1681 * Tell the alignment class about the scale factor.
1684 d2::align::set_scale(scale_factor
);
1690 d2::vise_core::set_scale(vise_scale_factor
);
1692 for (int opt
= 0; opt
< vise_count
; opt
++) {
1693 d2::vise_core::add(d2::render_parse::get(visp
[opt
* 4 + 0]),
1700 * Initialize non-incremental renderers
1704 if (usm_multiplier
!= 0) {
1707 * Unsharp Mask renderer
1710 ochain
[0] = new d2::usm(ochain
[0], scale_factor
,
1711 usm_multiplier
, inc
, response
[psf_linear
],
1712 response
[psf_nonlinear
], &input_exposure
[0]);
1719 * Point-spread function calibration renderer.
1720 * This renderer does not produce image output.
1721 * It is reserved for use with the point-spread
1722 * function calibration script
1723 * ale-psf-calibrate.
1726 ochain
[0] = new d2::psf_calibrate(ochain
[0],
1727 1, inc
, response
[psf_linear
],
1728 response
[psf_nonlinear
],
1731 } else if (ip_iterations
!= 0) {
1734 * Irani-Peleg renderer
1737 ochain
[0] = new d2::ipc( ochain
[0], ip_iterations
,
1738 inc
, response
[psf_linear
],
1739 response
[psf_nonlinear
],
1740 (exposure_register
== 1), ip_use_median
);
1744 * Handle the original frame.
1747 ui::get()->original_frame_start(argv
[i
]);
1749 for (int opt
= 0; opt
< oc_count
; opt
++) {
1750 ui::get()->set_orender_current(opt
);
1751 ochain
[opt
]->sync(0);
1753 ui::get()->writing_output(opt
);
1754 d2::image_rw::write_image(ochain_names
[opt
],
1755 ochain
[opt
]->get_image(0));
1759 d2::vise_core::frame_queue_add(0);
1761 ui::get()->original_frame_done();
1764 * Handle supplemental frames.
1767 for (unsigned int j
= 1; j
< d2::image_rw::count(); j
++) {
1769 const char *name
= d2::image_rw::name(j
);
1771 ui::get()->supplemental_frame_start(name
);
1774 * Write comment information about the
1775 * supplemental frame to the transformation
1776 * save file, if we have one.
1779 tsave_info (tsave
, name
);
1781 const d2::image
*im
= d2::image_rw::open(j
);
1782 d2::pixel apm
= im
->avg_channel_magnitude();
1783 tsave_apm(tsave
, apm
[0], apm
[1], apm
[2]);
1784 d2::image_rw::close(j
);
1786 for (int opt
= 0; opt
< oc_count
; opt
++) {
1787 ui::get()->set_orender_current(opt
);
1788 ochain
[opt
]->sync(j
);
1790 ui::get()->writing_output(opt
);
1791 d2::image_rw::write_image(ochain_names
[opt
],
1792 ochain
[opt
]->get_image(j
));
1796 d2::vise_core::frame_queue_add(j
);
1798 ui::get()->supplemental_frame_done();
1802 * Do any post-processing and output final image
1804 * XXX: note that non-incremental renderers currently
1805 * return zero for ochain[0]->sync(), since they write
1806 * output internally when inc != 0.
1809 for (int opt
= 0; opt
< oc_count
; opt
++)
1810 if ((ochain
[opt
]->sync() || !inc
) && !psf_match
)
1811 d2::image_rw::write_image(ochain_names
[opt
], ochain
[opt
]->get_image());
1814 * Output a summary match statistic.
1817 ui::get()->ale_done((double) d2::align::match_summary());
1820 * Perform any 3D tasks
1823 optimizations::begin_3d_work();
1827 d3::align::init_angle(view_angle
);
1829 d3::align::init_from_d2();
1831 if (d3::cpf::count() > 0) {
1832 d3::cpf::solve_3d();
1835 d3::align::write_alignments();
1837 d3::scene::set_filter_type(d3chain_type
);
1839 d3::scene::init_from_d2();
1841 // d3::scene::add_control_points();
1843 // d3::scene::relax_triangle_model();
1845 d3::scene::make_space(d3_depth
, d3_output
, &d3_depth_pt
, &d3_output_pt
);
1847 // fprintf(stderr, "Total pixels: %lu\n", d3::scene::total_pixels);
1848 // fprintf(stderr, "Total ambiguity: %lu\n", d3::scene::total_ambiguity);
1849 // fprintf(stderr, "Total tsteps: %lu\n", d3::scene::total_tsteps);
1850 // fprintf(stderr, "Total divisions: %lu\n", d3::scene::total_divisions);
1852 fprintf(stderr
, "Updating occupancy values");
1853 d3::scene::reduce_cost_to_search_depth(output_exposure
, inc
);
1854 fprintf(stderr
, ".\n");
1856 fprintf(stderr
, "Writing 3D output");
1857 d3::scene::d3px(d3px_count
, d3px_parameters
);
1859 for (unsigned int i
= 0; i
< d2::image_rw::count(); i
++) {
1860 assert (i
< d3_count
);
1862 if (d3_depth
[i
] != NULL
) {
1863 const d2::image
*im
= d3::scene::depth(i
);
1864 d2::image_rw::write_image(d3_depth
[i
], im
, output_exposure
, 1, 1);
1868 if (d3_output
[i
] != NULL
) {
1869 const d2::image
*im
= d3::scene::view(i
);
1870 d2::image_rw::write_image(d3_output
[i
], im
, output_exposure
);
1872 d3::focus::set_camera(view_count
++);
1875 for (std::map
<const char *, d3::pt
>::iterator i
= d3_output_pt
.begin();
1876 i
!= d3_output_pt
.end(); i
++) {
1878 const d2::image
*im
= d3::scene::view(i
->second
);
1879 d2::image_rw::write_image(i
->first
, im
, output_exposure
);
1881 d3::focus::set_camera(view_count
++);
1884 for (std::map
<const char *, d3::pt
>::iterator i
= d3_depth_pt
.begin();
1885 i
!= d3_depth_pt
.end(); i
++) {
1887 const d2::image
*im
= d3::scene::depth(i
->second
);
1888 d2::image_rw::write_image(i
->first
, im
, output_exposure
, 1, 1);
1892 fprintf(stderr
, ".\n");
1894 for (unsigned int i
= d2::image_rw::count(); i
< d3_count
; i
++) {
1895 if (d3_depth
[i
] != NULL
) {
1896 fprintf(stderr
, "\n\n*** Frame number for --3dd too high. ***\n\n");
1898 if (d3_output
[i
] != NULL
) {
1899 fprintf(stderr
, "\n\n*** Frame number for --3dv too high. ***\n\n");
1905 * Destroy the image file handler
1908 d2::image_rw::destroy();
1911 * Delete the transformation file structures, if any
1915 tsave_delete(tsave
);
1916 tload_delete(tload
);
1927 * If there was no output, the user might need more information.