From: <bru...@us...> - 2008-08-21 00:39:16
|
Revision: 871 http://panotools.svn.sourceforge.net/panotools/?rev=871&view=rev Author: brunopostle Date: 2008-08-21 00:39:26 +0000 (Thu, 21 Aug 2008) Log Message: ----------- match-n-shift --stacks option to use align_image_stack as well as autopano-sift when EXIF data suggests there are bracketed series Modified Paths: -------------- trunk/Panotools-Script/Changes trunk/Panotools-Script/bin/match-n-shift trunk/Panotools-Script/lib/Panotools/Script.pm Modified: trunk/Panotools-Script/Changes =================================================================== --- trunk/Panotools-Script/Changes 2008-08-12 03:28:10 UTC (rev 870) +++ trunk/Panotools-Script/Changes 2008-08-21 00:39:26 UTC (rev 871) @@ -4,6 +4,7 @@ - Read() and Write() accept STDIN and STDOUT using '-' placeholder - ptosort now allows sorting many aspects of .pto projects (Felix Hagemann) - Preserve 'disabled' flag for images (Felix Hagemann) + - match-n-shift --stacks option to use align_image_stack 0.15 - Fix for ptograph negative coordinates (Felix Hagemann) Modified: trunk/Panotools-Script/bin/match-n-shift =================================================================== --- trunk/Panotools-Script/bin/match-n-shift 2008-08-12 03:28:10 UTC (rev 870) +++ trunk/Panotools-Script/bin/match-n-shift 2008-08-21 00:39:26 UTC (rev 871) @@ -6,6 +6,7 @@ use Getopt::Long; use Pod::Usage; use Image::Size; +use Image::ExifTool; use Math::Trig; use Panotools::Script; use File::Temp qw/tempdir/; @@ -16,6 +17,7 @@ my $noransac = 0; my $matchpoint = 0; my $refine = 0; +my $dostacks = 0; my $projection = 0; my $deg_fov = 50; my $crop_s = undef; @@ -29,6 +31,7 @@ 'n|noransac' => \$noransac, 'm|matchpoint' => \$matchpoint, 'r|refine' => \$refine, + 'b|stacks' => \$dostacks, 'f|projection=i' => \$projection, 'v|fov=s' => \$deg_fov, 'k|selection=s' => \$crop_s, @@ -36,6 +39,8 @@ 'c|clean' => \$clean, 'h|help' => \$help); +# code assumes images are sorted +@ARGV = sort @ARGV; my @paths_input = @ARGV; pod2usage (-verbose => 2) if $help; @@ -53,6 +58,70 @@ my $tempdir = tempdir (CLEANUP => $clean); print STDERR "using $tempdir\n"; + +# try and so something sane with bracketed stacks +my $index_stack = 0; +if ($dostacks) +{ + my @photos = map (File::Spec->rel2abs ($_), @ARGV); + + my $speeds; + for my $path_photo (@photos) + { + my $exif_info = Image::ExifTool::ImageInfo ($path_photo, 'ExposureTime', 'ShutterSpeed'); + my $et = $exif_info->{ExposureTime} || $exif_info->{ShutterSpeed}; + $speeds->{$et} = 'TRUE'; + } + + my $brackets = scalar keys (%{$speeds}); + print STDERR "$brackets shutter speeds found.\n"; + die "Number of images not divisible by $brackets" if scalar (@photos) % $brackets; + + if ($brackets < 2) + { + print STDERR "Not attempting to align stacks.\n"; + $dostacks = 0; + } + next unless ($dostacks); + + my $longest; + for my $et (keys %{$speeds}) + { + $et =~ s/1\///; + $longest = $et unless defined $longest; + $longest = $et if $et < $longest; + } + + print STDERR "Longest exposure: $longest\n"; + + my $bases; + for my $path_photo (@photos) + { + my $exif_info = Image::ExifTool::ImageInfo ($path_photo, 'ExposureTime', 'ShutterSpeed'); + my $et = $exif_info->{ExposureTime} || $exif_info->{ShutterSpeed}; + push @{$bases}, $path_photo if $et eq "1/$longest"; + } + + my $stacks; + while (@photos) + { + my @stack; + push @stack, shift @photos for (1 .. $brackets); + push @{$stacks}, [@stack]; + } + + for my $stack (@{$stacks}) + { + my @projection = (); + @projection = ('-e') if ($projection == 2 or $projection == 3); + system ('align_image_stack', @projection, '-f', $deg_fov, '-p', File::Spec->catfile ($tempdir, "stack_$index_stack.pto"), @{$stack}); + $index_stack++; + } + + @paths_input = @{$bases}; +} + + my $index = 0; for my $path_input (@paths_input) @@ -182,21 +251,62 @@ $point->{Y} *= $N_scale_h; } -# fix image lines +# revert to original image filenames $index = 0; for my $image (@{$oto->Image}) { $image->{n} = '"'. $paths_input[$index] .'"'; - ($image->{w}, $image->{h}) = imgsize (File::Spec->rel2abs ($paths_input[$index])); + $index++; +} + +# merge stacks +if ($dostacks) +{ + my $tempfile = File::Spec->catfile ($tempdir, 'bases.oto'); + $oto->Write ($tempfile); + + my @ptos = ($tempfile); + + for my $i (0 .. $index_stack -1) + { + push @ptos, File::Spec->catfile ($tempdir, "stack_$i.pto"); + } + + my $temp_merged = File::Spec->catfile ($tempdir, 'merged.oto'); + system ('ptomerge', @ptos, $temp_merged); + my $temp_sorted = File::Spec->catfile ($tempdir, 'sorted.oto'); + system ('ptosort', '--image', 'n', $temp_merged, $temp_sorted); + $oto->Read ($temp_sorted); + $oto->Option->{outputLDRBlended} = 'false'; + $oto->Option->{outputLDRExposureBlended} = 'true'; +} + +# FIXME +$oto->Write ('abc'); + +$index = 0; +for my $image (@{$oto->Image}) +{ + ($image->{w}, $image->{h}) = imgsize (File::Spec->rel2abs ($ARGV[$index])); $image->{S} = $crop_s if defined $crop_s; # link all lens parameters $image->Set (v => '=0', d => '=0', e => '=0', + a => '=0', b => '=0', c => '=0', g => '=0', t => '=0', Ra => '=0', Rb => '=0', Rc => '=0', Rd => '=0', Re => '=0', Va => '=0', Vb => '=0', Vc => '=0', Vd => '=0', Vx => '=0', Vy => '=0') if ($index > 0); + $image->Set (v => $deg_fov, d => 0, e => 0, + a => 0, b => 0, c => 0, g => 0, t => 0, + Ra => 0, Rb => 0, Rc => 0, Rd => 0, Re => 0, + Va => 1, Vb => 0, Vc => 0, Vd => 0, Vx => 0, Vy => 0) + if ($index == 0); + $image->Set (f => $projection); $index++; } +# FIXME +$oto->Write ('def'); + if ($align) { my $tempfile = File::Spec->catfile ($tempdir, 'align.oto'); @@ -294,6 +404,7 @@ is generatekeys from autopano-sift-C -r | --refine Refine the found control points using the original images, delete unrefinable. + -b | --stacks Use align_image_stack with bracketed stacks -f | --projection Panotools style input projection number. Use 0 for rectilinear, 2 for circular fisheye and 3 for full-frame fisheye images. @@ -314,6 +425,9 @@ versions of the input photos, the resulting .oto file should be applicable to the original photos. +Additionally if the --stacks option is used then align_image_stack is used to +assemble bracketed sequences within the set, usually with less error. + =head1 LICENSE This program is free software; you can redistribute it and/or Modified: trunk/Panotools-Script/lib/Panotools/Script.pm =================================================================== --- trunk/Panotools-Script/lib/Panotools/Script.pm 2008-08-12 03:28:10 UTC (rev 870) +++ trunk/Panotools-Script/lib/Panotools/Script.pm 2008-08-21 00:39:26 UTC (rev 871) @@ -79,6 +79,7 @@ sub Read { my $self = shift; + $self->_defaults; my $path = shift || return 0; if ($path eq '-') { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |