Skip to content
Free public beta until December 4, 2026: every course is open, no card needed. After that, the first chapter of each course stays free and full access is a one-time $39 ($19 for up to 100 founding members chosen for helpful feedback). Your progress is kept. How the beta works

Recipe

Perspective-correct a photographed document (first pass)

Use when: a document was photographed at an angle instead of scanned flat, and you need a flat, rectangular result

Goal: a warped output image where the document's four corners land exactly on the output rectangle's four corners

Taught in Applied: perspective-correcting a photographed document

  1. 1

    Locate the (x,y) pixel coordinates of the document's four corners in the source photo. This first pass does it by hand; Chapter 10 automates it once edge and contour detection exist.

    Example

    The photographed page's corners read approximately (120,80), (940,110), (960,1300), (100,1260): top-left, top-right, bottom-right, bottom-left. Not a rectangle in the photo, since the camera's angle foreshortens the far edge.

    Why: every later step depends on these four points being right. An error here spreads through the whole pipeline as a warped-wrong result, not a crash. That makes this the step most worth double-checking by eye.

  2. 2

    Decide the flat output canvas's size, and assign each source corner to the matching destination corner, preserving the same corner order used in Step 1.

    Example

    An 850\times1100 output canvas gets destination corners (0,0), (850,0), (850,1100), (0,1100): matched top-left/top-right/bottom-right/bottom-left, the same order as Step 1's source corners.

    Why: matching order matters. Swapping even one correspondence's position in the list silently produces a mirrored or rotated result instead of an error, since the math has no way to know the labels were meant to line up differently.

  3. 3

    Feed the four correspondences into Section 8's linear system (or call cv2.getPerspectiveTransform directly) to recover the 3\times3 matrix.

    Example

    The four correspondences above solve to a specific H whose bottom row is not [0,0,1]. That confirms a genuine camera-angle warp was present, not just an affine skew a simpler matrix could have captured.

    Why: this is the step that actually captures the camera-angle warp, in numbers. Everything before it was measurement, and everything after it is just applying this one matrix.

  4. 4

    Apply H^{-1} as the output-to-source map (Section 5) across every output pixel, sampling with bilinear or bicubic interpolation (Section 6) rather than nearest-neighbor.

    Example

    The 850\times1100 canvas is filled pixel by pixel. A pixel near the photo's foreshortened far edge samples from a wider spread of nearby source pixels than a pixel near the near edge does. That directly reflects how much the camera's angle compressed that part of the photo.

    Why: skipping inverse mapping in favor of forward mapping would leave holes in the output (Section 5). That's exactly the failure mode this chapter's tools exist to avoid.

  5. 5

    Check that the four corners now land exactly on the output rectangle and the page edges read straight. Note that the result is still a raw grayscale or color warp, not yet a clean scan.

    Example

    The warped output has straight, rectangular edges, but keeps patchy lighting and a slightly gray background. Chapter 10's thresholding step is what turns this into a clean black-and-white scan.

    Why: naming what's still missing, rather than showing this as a finished scanner, is the honest scope this section promised in its own title.

Common mistakes

  • Picking source corners in a different turning order than destination corners (clockwise for one, counterclockwise for the other). This silently mirrors or rotates the result.
  • Using nearest-neighbor interpolation for the final warp. This leaves visibly jagged text edges where bilinear or bicubic would have stayed smooth.
  • Adding a fifth pair of corners "to be safe": four correspondences pin down a homography exactly (Section 8). A fifth over-determines the system and needs least-squares instead of an exact solve.