scanimage --mode Gray --resolution 300 >crooked.pgm pnmrotate -b white `pamtilt crooked.pgm` crooked.pgm >straight.pgm (then crop, threshold, etc.)
This program is part of Netpbm.
pamtilt tries to find the correct angle for untilting (de-skewing) a scanned text document. The output is a single floating-point number (the angle in degrees) for use as the argument to pnmrotate.
"Document skew" is the name given to what happens when you feed a page into an image scanner at an angle: the resulting image is tilted. pamtilt aims to correct that.
pamtilt makes three iterations at successively finer increments, testing prospective rotation angles to find the best one. pamtilt works best for straightening images with strong horizontal lines and does poorly with arbitrary photos. If pamtilt has no confidence in its results, it prints the special value 00.00; you can check for this or just pass it as a legal argument to pnmrotate.
pamtilt operates on the first plane of the input image, which is either PNM or PAM, and ignores any other planes. Ordinarily, the input is PGM or GRAYSCALE PAM, so there is only one plane.
pamtilt works on bilevel (PBM, BLACKANDWHITE PAM) images as well as grayscale, but you will minimize artifacts if you scan and rotate in grayscale before you apply a threshold to make a bilevel image.
A few options have general utility:
The default is 10.0.
Here are some other options you can use to tune the operation of pamtilt but they're seldom needed. The default values accommodate a wide variety of input documents.
The default is 1.0.
The default is 11.
The default is 5.
The default is 2.
The default is 1.0.
pamtilt implements a somewhat simplified algorithm inspired by: "Measuring Document Image Skew and Orientation", by Bloomberg, Kopec, and Dasari. In SPIE Volume 2422, Document Recognition II, pages 302-316, February 1995.
pamtilt was new in Netpbm 10.30 (October 2005).
Gregg Townsend wrote it and sent it to Bryan Henderson in August 2005. Bryan recoded it to fit Netpbm conventions.