{"id":67,"date":"2009-07-11T01:47:15","date_gmt":"2009-07-11T05:47:15","guid":{"rendered":"http:\/\/www.backgroundexposure.com\/blog\/?p=67"},"modified":"2025-03-08T22:09:46","modified_gmt":"2025-03-08T21:09:46","slug":"how-to-create-gigapixel-images","status":"publish","type":"post","link":"https:\/\/www.backgroundexposure.com\/blog\/2009\/07\/how-to-create-gigapixel-images\/","title":{"rendered":"The Biggest Picture"},"content":{"rendered":"<p>Ever since I found <a href=\"http:\/\/www.gigapan.org\/\" target=\"_blank\" rel=\"noopener\">GigaPan<\/a> and my friend <a href=\"http:\/\/www.aguntherphotography.com\/\" target=\"_blank\" rel=\"noopener\">Andre Gunther<\/a> wrote his guest article on <a href=\"http:\/\/www.backgroundexposure.com\/blog\/index.php\/2006\/12\/20\/stitching-very-large-panoramas-and-mosaics\/\" target=\"_self\">stitching large panoramas<\/a>, I&#8217;ve wanted to do one.\u00a0 While in Australia, I found a good subject: The Sydney night skyline, complete with Opera House and Harbor Bridge.\u00a0 I spent two hours standing in one spot while I worked out the best exposure and taking 220 distinct images.\u00a0 Each of these images was an 8-second exposure at ISO 200 and overlaps the previous one by about 25%.<\/p>\n<p>215 of these images are 3 rows of 50-some vertical photos at full zoom (200mm) plus another two rows capturing the tops of buildings and the top of the bridge.\u00a0 There was no point snapping a photo of empty space \u2014 there is nothing to anchor it to when stitching.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-86 aligncenter\" title=\"Source Images\" src=\"http:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/25-Sydney-Night-GigaPixel.jpg\" alt=\"Source Images\" width=\"480\" height=\"270\" srcset=\"https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/25-Sydney-Night-GigaPixel.jpg 480w, https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/25-Sydney-Night-GigaPixel-300x168.jpg 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p>The remaining 5 images were taken horizontally with an angle big enough to capture the full vertical.\u00a0 This would provide background imagery of the night sky and harbor that could not be photographed at full zoom and be attached to a landmark.\u00a0 Since neither the night sky nor an 8-second exposure of rippling water have any detail, nothing is lost.\u00a0 Note when using this technique: capture full-zoom images that just touch the foreground imagery so that the final stitch will have plenty of &#8220;quiet space&#8221; around the main content for blending smoothly into the background.<\/p>\n<p>And so ended the easy part.<\/p>\n<p>All of these images were shot in RAW mode because my camera has a 12-bit analog-to-digital converter and every bit is important given the huge dynamic range of night photography.\u00a0 I usually do these with HDR but if you&#8217;ve read my <a href=\"http:\/\/www.backgroundexposure.com\/blog\/index.php\/2007\/10\/17\/night-panorama-hdr\/\" target=\"_self\">previous HDR adventure<\/a> (and the <a href=\"http:\/\/www.backgroundexposure.com\/blog\/index.php\/2007\/12\/25\/more-punishment\/\" target=\"_self\">follow-up<\/a>) using only 11 images, you&#8217;ll understand why I was not about to do it with 220 images.<\/p>\n<p>Using Photoshop RAW converter, I optimized the exposure as best I could to reduce blown-out areas to the bare minimum and then converted them to 48-bit TIFFs (16 bits per channel) that the stitching software can read.<\/p>\n<p>When it came to the stitching, I tried both <a title=\"Excellent but very expensive panorama stitching software\" href=\"http:\/\/www.ptgui.com\/\" target=\"_blank\" rel=\"noopener\">PTgui<\/a> (v7, not the latest v8) and <a title=\"Execellent free panorama stitching software.\" href=\"http:\/\/hugin.sourceforge.net\/\" target=\"_blank\" rel=\"noopener\">Hugin<\/a>.\u00a0 Both behaved pretty much the same and both died horribly when trying to produce the final output.<\/p>\n<p>Creating the control points took a number of hours.\u00a0 The automated placement did a good job, covering about 80% of the pairs but some had none at all.\u00a0 I started the process with PTgui since it&#8217;s what I&#8217;ve used in the past; for many of the pairs with no control points, asking it to auto-generate points for just that pair usually produced good results.\u00a0 For the rest, I added a bunch by hand.\u00a0 Later, when using Hugin (which will read PTgui project files), I also added &#8220;vertical line&#8221; control points.\u00a0 These marvelous items tell the optimizer how to make perfectly straight panoramas without having to fiddle with it by hand in the preview pane.<\/p>\n<p>Hugin can also handle shots taken with different lenses or the same lens at different focal lengths.\u00a0 This was essential in making sure that the 5 &#8220;background&#8221; images were reasonably well aligned with the 215 &#8220;foreground&#8221; ones.\u00a0 PTgui (v7) had no such capacity.<\/p>\n<p>If I had known Hugin had these last two features (vertical line control points and support for different lenses), I never would have tried PTgui, but instead I didn&#8217;t switch to Hugin until PTgui proved useless at producing a final image.<\/p>\n<p>The problem, quite simply, was size.\u00a0 Once everything was assembled, I learned that the final image was to be over 3 GIGApixels in size!!!\u00a0 Multiply that by 3 colors and 16-bits (2 bytes) per pixel and you get an image that is over 18GB in size.\u00a0 Ouch!\u00a0 This is so big that PTgui couldn&#8217;t allocate a big enough memory chunk to even warp the images at full resolution.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-92\" title=\"gigapixel0101\" src=\"http:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel0101-215x300.jpg\" alt=\"gigapixel0101\" width=\"215\" height=\"300\" srcset=\"https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel0101-215x300.jpg 215w, https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel0101.jpg 230w\" sizes=\"auto, (max-width: 215px) 100vw, 215px\" \/>Hugin (or specifically, &#8220;nona&#8221;, the warping engine) has a nifty feature of keeping the warped output nearly the same size as the<br \/>\noriginal and include a position within a larger image encoded in the output file.\u00a0 PTgui wanted every warped output to be the full 3Gpx in size.<\/p>\n<p>Unfortunately, when it came to combining all the individual warped images, Enblend (the backend &#8220;blender&#8221; program of Hugin) died for the very same reason as PTgui: It couldn&#8217;t manage an 18GB image buffer, even held on disk, when compiled for a 32-bit operating system.\u00a0 I&#8217;m actually running Vista-64 but these programs were built in 32-bit mode and nobody had build 64-bit versions that I could find.<\/p>\n<p>I should mention that PTgui v8 is available as a 64-bit binary that <em>may<\/em> work&#8230;\u00a0 If you want to shell out USD$216 or so.<\/p>\n<p>Here&#8217;s another reason Hugin beats PTgui: It&#8217;s &#8220;free software&#8221;.\u00a0 The source code is readily available.\u00a0 I could easily download it and compile it as I needed.\u00a0 I chose a different path, though.\u00a0 I transferred the warped images to my laptop and then my Linux workstation at the office which is running a 64-bit distribution of Linux and has Hugin\/Enblend available.\u00a0 A little investigation into the Enblend command-line and a day later (including a lot of disk thrashing), I had a 6GB (compressed) TIFF file with the final image.<\/p>\n<p>Using my laptop as a network again, I transferred the result back home for final exposure adjustment in Photoshop.\u00a0 No luck.\u00a0 Photoshop (CS2) won&#8217;t read a 6GB TIFF file.\u00a0 In fact, TIFF doesn&#8217;t support files larger than 4GB &#8212; that darned 32-bit size thing again.<\/p>\n<p>Back at the office&#8230;\u00a0 This time I have Enblend stitch together one row of images at a time, producing 5 files only 1.5GB in size.\u00a0 These load into photoshop just fine but I don&#8217;t want to hand-blend the rows.<\/p>\n<p>Then I asked Enblend to combine adjacent rows (1&amp;2, 2&amp;3, 3&amp;4, and 4&amp;5).\u00a0 Since there is a gap between rows 1&amp;3, and 2&amp;4, there must be a stripe in which both the 1&amp;2 and 2&amp;3 composites are identical, meaning blending is just cutting one off with a straight line through that area.\u00a0 The output size of these row-pair images is about 2.7GB each.\u00a0 But&#8230;<\/p>\n<p>Photoshop still barfed on them.\u00a0 It seems that it cannot load TIFF files larger than even 2GB.\u00a0 What now?\u00a0 I&#8217;d already split it down to row-pairs.\u00a0 To make the files smaller, I&#8217;d have to start splitting it vertically as well.\u00a0 I didn&#8217;t want to do that much hand blending of the pieces, though, even if it would be just finding the overlapping regions.<\/p>\n<p>It occurred to me that perhaps I could split these large, blended files into smaller-sized tiles and then just butt them up against each other in Photoshop.\u00a0 A Google-search later, I found a program to split images into tiles.\u00a0 It&#8217;s $20 but has a trial version.\u00a0 I try it.\u00a0 It doesn&#8217;t support TIFF.\u00a0 Ah well, it probably wouldn&#8217;t handle huge images either.\u00a0 Another search later, I find a TIFF splitter.\u00a0 Same pay\/trial deal, but it turns out this only splits whole images from a multi-image file &#8212; completely useless to me.<\/p>\n<p>Okay, back to my roots.\u00a0 Way way back many centuries ago, not long after the Internet began, there existed a collection of image tools called PBM and eventually <a title=\"Free command-line image manipulation programs.\" href=\"http:\/\/netpbm.sourceforge.net\/\" target=\"_blank\" rel=\"noopener\">NetPBM<\/a>.\u00a0 This collection of command-line programs consists of binaries to convert pretty much every conceivable non-proprietary image format into a simple, uncompressed format and back, plus a large collection of programs that do various operations on images in this uncompressed format.<\/p>\n<p>For example, if you wanted to scale a PNG up 50% and convert it into a JPEG, you could do something like:<\/p>\n<pre>    pngtopam myimage.png \\\n        | pamscale 1.5 \\\n        | ppmtojpeg -quality=85 \\\n        &gt; mybigimage.jpg<\/pre>\n<p>The &#8220;ppm&#8221;, &#8220;pbm&#8221;, and &#8220;pam&#8221; names all mean different styles of the same basic format and almost all tools will read all formats.<\/p>\n<p>In this case, the tool I was looking for is &#8220;pamdice&#8221; which will take an input image and dice it into a number of rows and columns.\u00a0 By applying this to each row-pair, I can create files of manageable (read: loadable by Photoshop) size and put the whole thing together.<\/p>\n<p>Now that I had files that Photoshop could load, I created a canvas of the desired final size and pasted in the bottom row-pair.\u00a0 First the left half and then the right half.\u00a0 So far, so good.<\/p>\n<p>Adding the second row pair involved matching up the overlap.\u00a0 This is easily done coarsely with a full view.\u00a0 To align it precisely, zoom in to 100% (ctrl-alt-0) and set the blending option to &#8220;difference&#8221;.\u00a0 Then drag the new piece around until swaths of the screen turn black.\u00a0 Draw a line through this black area and &#8220;clear&#8221; (make transparent) the lower part of the upper row.\u00a0 Then change the blending back to &#8220;normal&#8221; and &#8220;merge down&#8221;.\u00a0 Repeat this with all row pairs.\u00a0 Forget keeping independent layers and using layer masks &#8212; the image is simply too large.\u00a0 There was enough waiting for swapping to disk as it was.<\/p>\n<p>Once all the rows were done, it was time to fix the things that Enblend did wrong.\u00a0 On a perfectly static scene, I might not have had to do anything.\u00a0 However, I had a scene with boats going by and some of the choices Enblend made were not correct.<\/p>\n<p>But no problem&#8230;\u00a0 Where a wrong choice was made, I simply cut &amp; pasted the raw warped image and position it using the same technique mentioned above.\u00a0 Then I would select the area I want, feather it, clear the rest, and merge it.\u00a0 After every major step, I&#8217;d save as PSB since PST won&#8217;t handle files this large.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-100 aligncenter\" src=\"http:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel-foreground480.png\" alt=\"\" width=\"480\" height=\"105\" srcset=\"https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel-foreground480.png 480w, https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel-foreground480-300x65.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p>Finally, it was time to combine the foreground and background images. I loaded the latter, scaled it up 4x\u2014 to match the resolution of the foreground, waited for photoshop, cut &amp; pasted the foreground, wait, wait, and wait some more while Photoshop writes 30<sup>+<\/sup>GB to its swap file, performed coarse placement of the foreground, wait, switched to &#8220;difference&#8221; blending and do fine placement, wait some more, etc.<\/p>\n<p>For final blending of the two, I used the lasso to draw about 2\/3 way between the landscape and the edge of the image.\u00a0 I then feathered this selection to make the transition go from 1\/3 of the way out to the end and cleared the outside.\u00a0 This turned out more difficult than I anticipated because, though I had used the same F-stop and shutter speed, the background images were brighter than the foreground ones.\u00a0 This required some compensation and very careful blending, but the result is nice, gentle transition that is invisible in the night sky and indistinguishable from depth-of-field or natural long-exposure blurring of water.<\/p>\n<p>Since I had deliberately underexposed all of the images to avoid blow-out in the highlights, as the last step I used some &#8220;curves&#8221; to brighten up the dark areas.\u00a0 With the extra bits from the raw capture, though, there&#8217;s no notable noise or posterization.<\/p>\n<p>A quick crop (well, okay&#8230;\u00a0 no operations are quick on an file this size) to the horizontal boundaries of the high-resolution imagery and it&#8217;s all finished.<\/p>\n<div id=\"attachment_103\" style=\"width: 490px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/share.gigapan.org\/viewGigapan.php?id=27822\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-103\" class=\"size-full wp-image-103\" src=\"http:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel1600.jpg\" alt=\"gigapixel1600\" width=\"480\" height=\"113\" srcset=\"https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel1600.jpg 800w, https:\/\/www.backgroundexposure.com\/blog\/wp-content\/uploads\/2009\/07\/gigapixel1600-300x70.jpg 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><p id=\"caption-attachment-103\" class=\"wp-caption-text\">Final Version (click for full-size viewing on GigaPan)<\/p><\/div>\n<p>Bonus:\u00a0 I&#8217;ll email the final full-size image to the first person who can identify the Andrew Lloyd Webber musical quoted above.\u00a0 \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ever since I found GigaPan and my friend Andre Gunther wrote his guest article on stitching large panoramas, I&#8217;ve wanted to do one. While in Australia, I found a good subject: The Sydney night skyline, complete with Opera House and Harbor Bridge. I spent two hours standing in one spot while I worked out the [&#8230;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-67","post","type-post","status-publish","format-standard","hentry","category-photography","odd"],"_links":{"self":[{"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/posts\/67","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/comments?post=67"}],"version-history":[{"count":24,"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/posts\/67\/revisions"}],"predecessor-version":[{"id":1269,"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/posts\/67\/revisions\/1269"}],"wp:attachment":[{"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/media?parent=67"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/categories?post=67"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.backgroundexposure.com\/blog\/wp-json\/wp\/v2\/tags?post=67"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}