#!/usr/bin/perl -T # jigsaw puzzle assembler, for e.g. Google Map tiles # A.Daviel, TRIUMF, Aug 2007 # assembles square image tiles into a Fig drawing by matching up the edges. # Edge matching is done by computing sum of distances in RGB colorspace between # corresponding pixels in 1-pixel-wide edge strips. # assumes current directory contains tile JPEGs. Tiles must currently be square # and must be all the same way up and the same size # A regex pattern ($filepat) is used to identify the correct tiles # a number of temporary files (*.rgb) are created and left around. If present, subsequent # script execution is faster # Note - Google maps and satellite images are copyright. Depending on jurisdiction, # you may be able to make single copies for private use or research purposes $T = 6000 ; # threshold for match - distance should be less than this for matches and more for mismatch $size = 256 ; # size of square tiles in pixels $filepat = '^(tqt.................jpg)$' ; # pattern to match tile name # tqtrtrtttstrqqqsrsr.jpg $filepat = '^(tq[\w]{17}.jpg)$' ; # pattern to match tile name $dbg = shift ; # debug flag $size3 = $size * 3 ; $sizem1 = $size - 1 ; $sizex1 = $size . 'x1' ; $ENV{PATH} = '/usr/bin' ; # need "convert" from ImageMagick package opendir (DIR1,".") or die "Opendir failed" ; foreach $_ (readdir (DIR1)) { if ($dbg>1) { print "$_\n" ; } unless (/$filepat/) { next ; } # pattern to match tile name $file1 = $1 ; push (@file,$file1) ; unless (-f "$file1.L.rgb") { system("convert -crop 1x$size+0+0 $file1 $file1.L.rgb") ; } unless (-f "$file1.R.rgb") { system("convert -crop 1x$size+$sizem1+0 $file1 $file1.R.rgb") ; } unless (-f "$file1.T.rgb") { system("convert -crop $sizex1+0+0 $file1 $file1.T.rgb") ; } unless (-f "$file1.B.rgb") { system("convert -crop $sizex1+0+$sizem1 $file1 $file1.B.rgb") ; } open (IN,"$file1.R.rgb") or die "Need $file1.R.rgb" ; $n = read (IN,$AR,$size3) ; unless ($n == $size3) { die "AR not $size3 bytes\n" ; } open (IN,"$file1.L.rgb") or die "Need $file1.L.rgb" ; $n = read (IN,$AL,$size3) ; unless ($n == $size3) { die "AL not $size3 bytes\n" ; } open (IN,"$file1.T.rgb") or die "Need $file1.T.rgb" ; $n = read (IN,$AT,$size3) ; unless ($n == $size3) { die "AT not $size3 bytes\n" ; } open (IN,"$file1.B.rgb") or die "Need $file1.B.rgb" ; $n = read (IN,$AB,$size3) ; unless ($n == $size3) { die "AB not $size3 bytes\n" ; } $D13m = $D24m = $D57m = $D68m = 999999; opendir (DIR,".") or die "Opendir failed" ; foreach $_ (readdir (DIR)) { unless (/$filepat/) { next ; } # pattern to match tile name $file = $1 ; if ($file eq $file1) { next ; } unless (-f "$file.L.rgb") { if ($dbg>1) { print "convert -crop 1x$size+0+0 $file $file.L.rgb\n" ; } system("convert -crop 1x$size+0+0 $file $file.L.rgb") ; } unless (-f "$file.R.rgb") { if ($dbg>1) { print "convert -crop 1x$size+$sizem1+0 $file $file.R.rgb\n" ; } system("convert -crop 1x$size+$sizem1+0 $file $file.R.rgb") ; } unless (-f "$file.T.rgb") { if ($dbg>1) { print "convert -crop $sizex1+0+0 $file $file.T.rgb\n" ; } system("convert -crop $sizex1+0+0 $file $file.T.rgb") ; } unless (-f "$file.B.rgb") { if ($dbg>1) { print "convert -crop $sizex1+0+$sizem1 $file $file.B.rgb\n" ; } system("convert -crop $sizex1+0+$sizem1 $file $file.B.rgb") ; } open (IN,"$file.L.rgb") or die "Need $file.L.rgb" ; $n = read (IN,$BL,$size3) ; unless ($n == $size3) { print "$file BL not $size3 bytes\n" ; next ; } open (IN,"$file.R.rgb") or die "Need $file.R.rgb" ; $n = read (IN,$BR,$size3) ; unless ($n == $size3) { print "$file BR not $size3 bytes\n" ; next ; } open (IN,"$file.T.rgb") or die "Need $file.T.rgb" ; $n = read (IN,$BT,$size3) ; unless ($n == $size3) { print "$file BT not $size3 bytes\n" ; next ; } open (IN,"$file.B.rgb") or die "Need $file.B.rgb" ; $n = read (IN,$BB,$size3) ; unless ($n == $size3) { print "$file BB not $size3 bytes\n" ; next ; } @pix1 = split(//,$AR) ; @pix2 = split(//,$AL) ; @pix5 = split(//,$AT) ; @pix6 = split(//,$AB) ; @pix3 = split(//,$BL) ; @pix4 = split(//,$BR) ; @pix7 = split(//,$BB) ; @pix8 = split(//,$BT) ; $D13 = $D24 = $D57 = $D68 = 0 ; for ($i=0;$i<$size;$i++) { $r1 = ord(shift(@pix1)) ; $g1 = ord(shift(@pix1)) ; $b1 = ord(shift(@pix1)) ; $r2 = ord(shift(@pix2)) ; $g2 = ord(shift(@pix2)) ; $b2 = ord(shift(@pix2)) ; $r3 = ord(shift(@pix3)) ; $g3 = ord(shift(@pix3)) ; $b3 = ord(shift(@pix3)) ; $r4 = ord(shift(@pix4)) ; $g4 = ord(shift(@pix4)) ; $b4 = ord(shift(@pix4)) ; $r5 = ord(shift(@pix5)) ; $g5 = ord(shift(@pix5)) ; $b5 = ord(shift(@pix5)) ; $r6 = ord(shift(@pix6)) ; $g6 = ord(shift(@pix6)) ; $b6 = ord(shift(@pix6)) ; $r7 = ord(shift(@pix7)) ; $g7 = ord(shift(@pix7)) ; $b7 = ord(shift(@pix7)) ; $r8 = ord(shift(@pix8)) ; $g8 = ord(shift(@pix8)) ; $b8 = ord(shift(@pix8)) ; $d13 = sqrt( ($r1-$r3)**2 + ($b1-$b3)**2 + ($g1-$g3)**2 ) ; $D13+= $d13 ; $d24 = sqrt( ($r2-$r4)**2 + ($b2-$b4)**2 + ($g2-$g4)**2 ) ; $D24+= $d24 ; $d57 = sqrt( ($r5-$r7)**2 + ($b5-$b7)**2 + ($g5-$g7)**2 ) ; $D57+= $d57 ; $d68 = sqrt( ($r6-$r8)**2 + ($b6-$b8)**2 + ($g6-$g8)**2 ) ; $D68+= $d68 ; } $D13 = int($D13) ; $D24 = int($D24) ; $D57 = int($D57) ; $D68 = int($D68) ; if ($dbg) { print "$file AR-BL $D13 AL-BR $D24 AT-BB $D57 AB-BT $D68\n" ; } # unless(defined($D13m)) { $D13m = $D13 ; } # unless(defined($D24m)) { $D24m = $D24 ; } # unless(defined($D57m)) { $D57m = $D57 ; } # unless(defined($D68m)) { $D68m = $D68 ; } if ($D13<$D13m) { $D13m = $D13 ; $left = $file ; } if ($D24<$D24m) { $D24m = $D24 ; $right= $file ; } if ($D57<$D57m) { $D57m = $D57 ; $botm = $file ; } if ($D68<$D68m) { $D68m = $D68 ; $top = $file ; } } print "$file1 is\n" ; if ($D13m < $T) { $leftof{$file1} = $left ; print " Left of $left ($D13m)\n" ; } if ($D24m < $T) { $rightof{$file1} = $right ; print " Right of $right ($D24m)\n" ; } if ($D68m < $T) { $above{$file1} = $top ; print " Above $top ($D68m)\n" ; } if ($D57m < $T) { $below{$file1} = $botm ; print " Below $botm ($D57m)\n" ;} } $x{$file[0]} = 10 ; $y{$file[0]} = 10 ; for ($k=0;$k<4;$k++) { foreach $file (@file) { if ($x{$file}) { if ($leftof{$file}) { $x{$leftof{$file}} = $x{$file} + 1 ; $y{$leftof{$file}} = $y{$file} ; } if ($rightof{$file}) { $x{$rightof{$file}} = $x{$file} - 1 ; $y{$rightof{$file}} = $y{$file} ; } if ($above{$file}) { $x{$above{$file}} = $x{$file} ; $y{$above{$file}} = $y{$file} +1 ; } if ($below{$file}) { $x{$below{$file}} = $x{$file} ; $y{$below{$file}} = $y{$file} - 1 ; } } } } open (OUT,">tiles.fig") ; print OUT<