#!/usr/bin/perl -w # Copyright 2003, 2004 David Hilvert , # # This file is part of the Anti-Lamenessing Engine. # # The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # The Anti-Lamenessing Engine is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Anti-Lamenessing Engine; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # This script attempts to calibrate a filter under ALE for characteristics of a # specific device. It uses the stdin IPC device to configure the filter. # # The initial filter tested is the box filter, and individual elements # of the filter are increased or decreased to determine the effects of # such changes. When the change increases the match with the desired # output, it is kept. Otherwise, the change is backed out. # # The magnitude of change tested is determined by an increment variable, # which starts at a user-defined value and is halved until it is smaller # than 0.1 (an arbitrary value which could easily be changed). # # For every increment value, all elements are tested with positive and negative # changes of this magnitude. If an element fails to offer any error # improvement on a given pass, it is skipped on all future passes for the same # increment value. # # Passes at a given increment value continue until all elements are skipped, at # which point the magnitude is halved. # # It may be a good idea to use this script with relatively small images, as # large images may require a long time to process. # # Remove these two lines to run the script. # # Note: This script has been manually updated for ALE 0.7.0 from a non-generic # working copy, and hence may contain serious bugs. Bugs may be reported to # ale@ventricle.dyndns.org. # print "Edit this script to set relevant parameters for calibration.\n"; exit 1; # # The diameter of the filter, in pixels. Set nlheight to zero to disable # non-linear filtering. # $lheight = 3; $lwidth = 3; $nlheight = 0; $nlwidth = 0; # # Filter rows and columns # $lrows = 3; $lcols = 3; $nlrows = 0; $nlcols = 0; # # These are the input images used for calibration # # inputs: input images. # # tfile: transformation file indicating the proper transformations for the # input images. # $inputs = "*.ppm"; $tfile = "b.t"; # # Factor (>= 1) by which to scale each of the input images. # $scale = 5; # # Comparison images used for calibration. # # Either: # # (a) set $comparison to the known scene data, or # # (b) set $comparison_inputs for calibration frames taken with the same imaging # device (at a larger scale). $comparison_tfile indicates the alignment of # $comparison_inputs. # $comparison = "c-align.png"; # $comparison_inputs = "comparison/*.ppm"; # $comparison_tfile = "comparison/b.t"; # # Random (but non-uniform) temporary files # $output1 = "/tmp/ale1-$$.png"; $temp_file = "/tmp/ale-$$-input"; $result_file = "/tmp/ale-$$-results"; $comparison = "/tmp/ale-$$-comparison.ppm" if defined $comparison_inputs; # # Initialize a box filter. # @lfilter = (((1.0) x $lrows) x $lcols) x 3; @nlfilter = (((1.0) x $nlrows) x $nlcols) x 3; # # Alternatively, something like this can be used: # # @lfilter = ( # 1, 1, 1, # 1, 1, 1, # 3, 4, 5.3, # . # . # . #) # # Or: # # $lfilter = "1 0.5 ... 3" # # @lfilter = split / /, $filter; # # # Affine colorspace parameters # @affine_mul = (1, 1, 1); @affine_add = (0, 0, 0); # # When modifying the filter, we start by modifying each element by $increment. # We halve the amount until we reach a value smaller than $increment_lower. # $a*_multiplier scales the increment for @affine_add and @affine_mul. # $increment = 0.8; $increment_lower = 0.01; $am_multiplier = 0.01; $aa_multiplier = 0.01; # # This array indicates the last direction tried for each index. Since we # haven't tried anything yet, initialize this to +1 for all indices. # # +1 ==> positive change # -1 ==> negative change # @llast_dir = (((1.0) x $lcols) x $lrows) x 3; @nllast_dir = (((1.0) x $nlcols) x $nlrows) x 3; # # Program name to invoke ale # $invocation = "ale"; # # Subroutine to obtain the match value associated with the current filter. # sub foo { `echo $lheight > $temp_file`; `echo $lwidth >> $temp_file`; `echo $lrows >> $temp_file`; `echo $lcols >> $temp_file`; foreach $elem (@lfilter) { `echo $elem >> $temp_file`; } if ($nlheight > 0) { `echo $nlheight >> $temp_file`; `echo $nlwidth >> $temp_file`; `echo $nlrows >> $temp_file`; `echo $nlcols >> $temp_file`; foreach $elem (@nlfilter) { `echo $elem >> $temp_file`; } } if ($nlheight > 0) { `$invocation --dchain triangle:2 --no-inc --mc 1 --ips 4 --lpsf stdin --nlpsf stdin --projective --perturb-upper=0 --trans-load=$comparison_tfile $comparison_inputs $comparison < $temp_file 2> /dev/null` if ($init_comparison && $comparison_inputs); `$invocation --dchain triangle:2 --no-inc --mc 1 --scale=$scale --lpsf stdin --nlpsf stdin --psf-match @affine_mul @affine_add --projective --perturb-upper=0 --trans-load=$tfile $inputs $comparison $output1 < $temp_file 2> $result_file`; } else { `$invocation --dchain triangle:2 --no-inc --mc 1 --ips 4 --lpsf stdin --projective --perturb-upper=0 --trans-load=$comparison_tfile $comparison_inputs $comparison < $temp_file 2> /dev/null` if ($init_comparison && $comparison_inputs); `$invocation --dchain triangle:2 --no-inc --mc 1 --scale=$scale --lpsf stdin --psf-match @affine_mul @affine_add --projective --perturb-upper=0 --trans-load=$tfile $inputs $comparison $output1 < $temp_file 2> $result_file`; } `rm -f $output1`; `rm -f $temp_file`; $data = `cat $result_file`; `rm -f $result_file`; $data =~ /::\s*(\S+)/ or die "Couldn't get match value.\n"; $data = $1; print "Measured Error: " . $data . "\n"; $_ = $1; } $curval = foo(); while ($increment >= $increment_lower) { $changed = 0; for $i (0 .. $lrows - 1) { for $j (0 .. $lcols - 1) { for $k (0 .. 2) { $index = $k + 3 * ($j + $lcols * $i); if ($lskip[$index]) { print "Skipping linear element: " . $index . "\n"; next; } else { print "Testing linear element: " . $index . "\n"; } $dir_incr = $increment * $llast_dir[$index]; $lfilter[$index] += $dir_incr; $newval = foo(); if ($newval < $curval) { $changed = 1; $curval = $newval; if ($nlheight > 0) { print "Filter: " . "$lheight $lwidth $lrows $lcols @lfilter $nlheight $nlwidth $nlrows $nlcols @nlfilter\n"; } else { print "Filter: " . "$lheight $lwidth $lrows $lcols @lfilter\n"; } } else { $lfilter[$index] -= 2 * $dir_incr; $newval = foo(); if ($newval < $curval) { $changed = 1; $curval = $newval; if ($nlheight > 0) { print "Filter: " . "$lheight $lwidth $lrows $lcols @lfilter $nlheight $nlwidth $nlrows $nlcols @nlfilter\n"; } else { print "Filter: " . "$lheight $lwidth $lrows $lcols @lfilter\n"; } $llast_dir[$index] *= -1; } else { $lfilter[$index] += $dir_incr; $lskip[$index] = 1; } } }}} if ($nlheight > 0) { for $i (0 .. $nlrows - 1) { for $j (0 .. $nlcols - 1) { for $k (0 .. 2) { $index = $k + 3 * ($j + $nlcols * $i); if ($nlskip[$index]) { print "Skipping non-linear element: " . $index . "\n"; next; } else { print "Testing non-linear element: " . $index . "\n"; } $dir_incr = $increment * $nllast_dir[$index]; $nlfilter[$index] += $dir_incr; $newval = foo(); if ($newval < $curval) { $changed = 1; $curval = $newval; print "Filter: " . "$lheight $lwidth $lrows $lcols @lfilter $nlheight $nlwidth $nlrows $nlcols @nlfilter\n"; } else { $nlfilter[$index] -= 2 * $dir_incr; $newval = foo(); if ($newval < $curval) { $changed = 1; $curval = $newval; print "Filter: " . "$lheight $lwidth $lrows $lcols @lfilter $nlheight $nlwidth $nlrows $nlcols @nlfilter\n"; $nllast_dir[$index] *= -1; } else { $nlfilter[$index] += $dir_incr; $nlskip[$index] = 1; } } }}}} if ($changed == 0) { @lskip = (); @nlskip = (); $increment /= 2; print "Increment: $increment\n"; } }