A document scanner app does three things to a phone photo: it finds the paper, warps its four corners into a rectangle, and turns the result into ink and paper. None of the three is exotic, but each has a place where it quietly goes wrong. The PDF Editor in the osFoundry desktop app does this with four corner handles and a Black and white button. This post rebuilds the same pipeline in Python with OpenCV and measures it, because there is a way to score it exactly: the photo is one I generated myself, so the page that was "printed" and the corners it was placed at are both known.
The test photo
make_scan.py renders page one of a made-up lease with Pillow (Times New Roman, 1275 × 1650, Letter at 150 dpi), then shoots it virtually: a perspective transform onto a 1500 × 2000 canvas, a wood-grain table, a soft shadow under the paper, brightness falling off toward the bottom right, a little noise and a JPEG at quality 82.…