320 lines
8.5 KiB
Perl
Executable File
320 lines
8.5 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
# Copyright 2003, 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
|
|
# <dhilvert@ugcs.caltech.edu>
|
|
|
|
# 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";
|
|
}
|
|
}
|
|
|