From: <bru...@us...> - 2008-02-07 23:57:13
|
Revision: 808 http://panotools.svn.sourceforge.net/panotools/?rev=808&view=rev Author: brunopostle Date: 2008-02-07 15:57:13 -0800 (Thu, 07 Feb 2008) Log Message: ----------- This is for use in hugin as an an autopano-sift-c wrapper, it does all the usual autopano stuff except it does it on temporary stereographic versions of the photos. This is all done behind the scenes so all you have to do is to specify the projection type of your photos and an approximate field of view. I'd recommend also using --finetune option as this is better done in stereographic space in principle. Only tested on fisheye images, rectilinear should work but has had no testing. Modified Paths: -------------- trunk/Panotools-Script/bin/match-n-shift Modified: trunk/Panotools-Script/bin/match-n-shift =================================================================== --- trunk/Panotools-Script/bin/match-n-shift 2008-02-06 17:24:23 UTC (rev 807) +++ trunk/Panotools-Script/bin/match-n-shift 2008-02-07 23:57:13 UTC (rev 808) @@ -2,63 +2,166 @@ use strict; use warnings; +use File::Spec::Functions; +use Getopt::Long; +use Pod::Usage; +use Image::Size; use Math::Trig; use Panotools::Script; +use File::Temp qw/tempdir/; -# Wrapper to run autopano-sift on stereographic versions of photos -# -# Bruno Postle - February 2008 -# -# UNFINISHED -# -# Stuff done so far: Takes an .oto file generated by autopano-sift and rewrites -# the control point coordinates assuming that they are based on temporary -# stereographic versions of the input photos, the resulting .oto file should be -# applicable to the original photos. -# Recommend using --noransac for fisheyes and --points 100 +# TODO test rectilinear photos -# TODO -# -# create the stereographic images via ImageMagick and nona -# replace autopano-complete.sh logic -# test rectilinear photos -# delete points that end up on boundary (may happen with rectilinear input) -# requires --fov and --projection parameters which need to be supplied by hugin -# projection and FoV need to be set in .oto files +my $path_oto; +my $pix_max = 800; +my $points = 10; +my $noransac = 0; +my $refine = 0; +my $projection = 0; +my $deg_fov = 50; +my $clean = 0; +my $help = 0; -my $path_pto = shift || die 'supply an input pto file'; -my $path_pto_out = shift || die 'supply an output pto file'; +GetOptions ('o|output=s' => \$path_oto, + 's|size=i' => \$pix_max, + 'p|points=i' => \$points, + 'n|noransac' => \$noransac, + 'r|refine' => \$refine, + 'f|projection=i' => \$projection, + 'v|fov=f' => \$deg_fov, + 'c|clean' => \$clean, + 'h|help' => \$help); -my $pto = new Panotools::Script; -$pto->Read ($path_pto); +my @paths_input = @ARGV; -for my $point (@{$pto->Control}) +pod2usage (-verbose => 2) if $help; +pod2usage (2) unless (defined $path_oto and scalar @paths_input > 1); + +# disable ransac for wideangle shots +my $ransac = 1; $ransac = 0 if ($noransac or $deg_fov > 60); +# extra refine options +my @refine = (); @refine = ('--refine', '--keep-unrefinable', 0) if $refine; + +my @paths_key = (); +my @paths_output = (); + +my $tempdir = tempdir (CLEANUP => $clean); +print STDOUT "using $tempdir\n"; + +my $index = 0; + +for my $path_input (@paths_input) { - my $n = $pto->Image->[$point->{n}]; + # create a smaller version of the original photo + my $path_input_small = catfile ($tempdir, "small_$index.tif"); + system ('convert', '-depth', 8, '-geometry', $pix_max.'x'.$pix_max, + $path_input, $path_input_small); + # create small stereographic version + my ($pix_width, $pix_height) = imgsize ($path_input_small); + my $path_pto_temp = catfile ($tempdir, "$index.pto"); + + # don't use stereographic is projection isn't azimuthal + my $projection_panorama = 4; + $projection_panorama = 1 if $projection == 1; + $projection_panorama = 2 if $projection == 4; + + my $pto = new Panotools::Script; + $pto->Panorama->Set (v => $deg_fov, E => 0, f => $projection_panorama, u => 0, + w => $pix_width, h => $pix_height, n => '"TIFF"'); + $pto->Image->[0] = new Panotools::Script::Line::Image; + $pto->Image->[0]->Set (w => $pix_width, h => $pix_height, v => $deg_fov, + f => $projection, Eev => 0, r => 0, p => 0, y => 0, n => "\"$path_input_small\""); + $pto->Write ($path_pto_temp); + + my $path_output_small = catfile ($tempdir, "sgraph_$index.tif"); + + system ('nona', '-p', 'UINT8', '-o', $path_output_small, $path_pto_temp); + $index++; + push @paths_output, $path_output_small; + + # create XML keyfile for stereographic version + my $path_key = "$path_output_small.key"; + push @paths_key, $path_key; + next if (-e $path_key and not $clean); + system ('generatekeys', $path_output_small, $path_key, $pix_max + 1); +} + +# create a project file based on the keyfiles +system ('autopano', @refine, '--ransac', $ransac, + '--maxmatches', $points, $path_oto, @paths_key); + +# delete temporary keyfiles +for my $path_key (@paths_key) +{ + unlink $path_key if ($clean); +} + +# Read in the generated project file +my $oto = new Panotools::Script; +$oto->Read ($path_oto); + +# fix control points +for my $point (@{$oto->Control}) +{ + my $n = $oto->Image->[$point->{n}]; + + $n->{v} = $deg_fov; + $n->{f} = $projection; + my $n_fov = $n->{v}; - $n_fov = $pto->Image->[$1]->{v} if ($n_fov =~ /^=([[:digit:]]+)/); + $n_fov = $oto->Image->[$1]->{v} if ($n_fov =~ /^=([[:digit:]]+)/); + # first convert back from stereographic ($point->{x}, $point->{y}) = from_sgraphic ({ rad_fov => deg2rad ($n_fov), projection => $n->{f}, pix_x => $point->{x}, pix_y => $point->{y}, pix_width => $n->{w}, pix_height => $n->{h}}); - my $N = $pto->Image->[$point->{N}]; + # scale back to original image dimensions + my ($n_pix_width, $n_pix_height) = imgsize ($paths_input[$point->{n}]); + my $n_scale_w = $n_pix_width / $n->{w}; + my $n_scale_h = $n_pix_height / $n->{h}; + $point->{x} *= $n_scale_w; + $point->{y} *= $n_scale_h; + + my $N = $oto->Image->[$point->{N}]; + + $N->{v} = $deg_fov; + $N->{f} = $projection; + my $N_fov = $N->{v}; - $N_fov = $pto->Image->[$1]->{v} if ($N_fov =~ /^=([[:digit:]]+)/); + $N_fov = $oto->Image->[$1]->{v} if ($N_fov =~ /^=([[:digit:]]+)/); + # first convert back from stereographic ($point->{X}, $point->{Y}) = from_sgraphic ({ rad_fov => deg2rad ($N_fov), projection => $N->{f}, pix_x => $point->{X}, pix_y => $point->{Y}, pix_width => $N->{w}, pix_height => $N->{h}}); + + # scale back to original image dimensions + my ($N_pix_width, $N_pix_height) = imgsize ($paths_input[$point->{N}]); + my $N_scale_w = $N_pix_width / $N->{w}; + my $N_scale_h = $N_pix_height / $N->{h}; + $point->{X} *= $N_scale_w; + $point->{Y} *= $N_scale_h; } -$pto->Write ($path_pto_out); +# fix image lines +$index = 0; +for my $image (@{$oto->Image}) +{ + $image->{n} = '"'. $paths_input[$index] .'"'; + ($image->{w}, $image->{h}) = imgsize ($paths_input[$index]); + $index++; +} +$oto->Write ($path_oto); + +# voodoo sub from_sgraphic { my $args = shift; @@ -123,3 +226,55 @@ exit 0; +__END__ + +=head1 NAME + +match-n-shift - wrapper to run autopano-sift on stereographic versions of photos + +=head1 SYNOPSIS + +match-n-shift [options] --output project.pto image1 image2 [...] + + Options: + -o | --output name Filename of created panorama project + -s | --size number Downsize images until width and height is + smaller than number, default 800 + -p | --points number Number of generated control points between, + each pair, default: 10 + -n | --noransac No ransac detection, useful for fisheye images + -r | --refine Refine the found control points using the + original images, delete unrefinable. + -f | --projection Panotools style input projection number + -v | --fov Horizontal field of view in degrees + -c | --clean Do not reuse keypoints detected in earlier runs, + deletes old keypoint files. + -h | --help Outputs help documentation. + +=head1 DESCRIPTION + +B<match-n-shift> takes a list of image files and creates a hugin +compatible project file containing control points linking the images together. + +It does this by creating scaled stereographic versions of the original photos +and identifying control points, then takes the generated .oto file and rewrites +the control point coordinates assuming that they are based on stereographic +versions of the input photos, the resulting .oto file should be applicable to +the original photos. + +=head1 LICENSE + +This file is licensed under the same terms as autopano-sift-C itself + +=head1 SEE ALSO + +L<http://hugin.sourceforge.net/> +L<http://cs.tu-berlin.de/~nowozin/autopano-sift/> + +=head1 AUTHOR + +Bruno Postle - February 2008. + +=cut + +=begin perl This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |