Cleaning Scans

Scanning documents or books without expensive hardware and commercial software can be tricky. This week, I give you the script I use to clean up a scanned image (and eventually assemble many of them into a single PDF document).

scanner

The first step is to scan the material with your favorite scanner and try to already make a good job of it. Typically, even if you did your best, it’ll end up looking something like:

out0092

Which isn’t too bad but 1) is somewhat skewed and 2) shows uninteresting things such as the book’s binding and other background elements. We want to crop that automagically and deskew the image. To deskew the image, I use Fred Weinhau’s textdeskew script, built upon Imagemagick and Awk. Unfortunately, crop isn’t quite automated yet. The script looks like:

#!/usr/bin/env bash

for z in *.png
do
    convert $z \
            -crop 1625x2600+50+50 \
            -gravity center \
            -background white \
            -extent 1800x2700 \
            +repage tmp.png
    ./text-deskew.sh tmp.png crop-rot-$z
done

This produces this image:

crop-rot-out0092

Now, if we’re going to bundle the images into a DjVu file, filling the border with white might not be the best course. However, if you rather intend to assemble the image in a somewhat lightweight PDF file, you might want to threshold it into a b/w image. To do so, I use Imagemagick. But Imagemagick is full of idiosyncrasies and is especially finnicky.

Here’s the thresholding script:

#!/usr/bin/env bash
base=$(dirname $0)

files=($((
       for f in $@
       do
           echo $f
       done
       ) | sort))

c=0
for z in ${files[@]}
do
    # threshold
    convert -verbose \
            "$z" \
            -unsharp 5x5 \
            -colorspace gray \
            +dither \
            -remap ${base}/bw.gif\
            -normalize \
            -threshold 70% \
            png:bw-"${z//.*}.png"
done

The script applies an unsharp mask to enhance somewhat details, then uses another image’s palette (a 1×1 pixels GIF containing a 2-color palette) to remap the colors of the original image after normalization and thresholding.

You can download the 1×1 pixels bw.gif here.

At last, we get the final image:

bw-crop-rot-out0092

*
* *

These scripts are somewhat brittle, principally because Imagemagick is really finicky. The order of the options passed to the convert command has to be exactly right, otherwise it won’t work, it’ll do some other random thing. So, use at your own risks, an all that.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: