modified on 12 February 2012 at 18:59 ••• 1,597 views


From MairasNetWiki

Jump to: navigation, search



Once upon a time (in summer 2006), I had the idea of scanning the nautical charts of the Turku archipelago on computer and combining the individual chart pages to one humongous panorama file. As I had played with hugin to create photographic panoramas, I thought I could use it to stitch scanned files as well. Even though there even is a tutorial for stitching flat scanned images with hugin, it didn't really work out for panoramas of 140 or so images. So, I began working on my own implementation.

First, I just used Autopano-SIFT to create control points for the files and implemented my own optimizer to align and translate the bitmaps. The translated bitmaps would then be stitched with enblend. This worked almost well enough, but not quite. In some of the images, Autopano-SIFT would make enough errors to misalign the images.

Since the images are of same scale, I thought use of Autopano-SIFT might be overkill. Instead, I implemented the alignment algorithms myself. First, I implemented an image straightening algorithm based on Canny edge detection and Hough transforms. This would search for any near-horizontal or near-vertical lines in the image and rotate the image to make them perfectly aligned. This is implemented in, and works perfectly. Second, the straightened images are aligned by calculating the offsets using 2D phase correlation and translating the images accordingly. Due to the size of the images, I unfortunately cannot calculate the phase correlation on the original bitmaps, but have to scale them down to get an initial estimate of the offset and then refine the estimate using smaller portions of the images. However, the results speak for themselves. The worst alignment errors are on the scales of a few pixels.


As the original charts are copyright, I cannot put the stiched files available as-is. Instead, a scaled-down version of the full-size file can be found below, together with a couple of close-ups.

Click the thumbnails to open the full-size images!

A scaled-down version of the full chart series D. The original picture is 15197x19995 pixels in size.

A zoomed-in sample. This location has numerous stitch lines, but rather small alignment errors.


Currently, mapstitch consists of a few Python scripts (which do all the really interesting bits), and snippets of shell code and a makefile to glue the stuff together.

First, scan your charts. For example xsane works nice, as it allows you to scan to sequentially numbered saved files with a single mouse click. Never mind the orientation of the single pages, as such are easy to remedy later. Just scan the charts as rapidly as possible. You might even watch a movie while doing that. :-)

If your scanned images need cropping (to remove vignetted corners, chart margins, or otherwise), it's easiest to do it now. This is what I did.

for n in `every 1,3/4 s*.png` ; do
    convert -crop 1450x2031+0+0 $n cropped/$n

for n in `every 2,4/4 s*.png` ; do
    convert -crop 1450x2031+246+0 $n cropped/$n

If some of your scanned pages need 180° rotation, do it now. This is why I wrote the every-n script:

for n in `every 3-4/4 cropped/s*.png`; do
    mogrify -rotate 180 $n

Next, straighten the images with the script. Note that the straighten script works also perfectly well for rotating other scanned material such as pages of text!

mkdir straight
cd cropped
for n in s*.png ; do $n ../straight/$n

Now, feed all the pages to and hope for the best! As the current implementation requires every scanned image to be connected to two other images, the automatic alignment algorithm may fail to find the connections for areas where not enough pages overlap. In such cases, the connections can be forced using the --pair option. -o ../all.tif s*.png


Mapstitch is licenced under GPLv2.



Mapstitch depends on quite a few Python packages. On an Ubuntu system, you can install the packages by issuing the following command:

sudo apt-get install python-imaging python-matplotlib python-scipy python-yapgvb