Photo Editing

Perspective Correction: Four Corners and One Matrix Put It Straight

A photo taken at an angle is a projective map, not an affine one, which is why cropping and rotating cannot repair it. Four corners supply the eight numbers that can, and the geometry of the vanishing points can even hand back the object's true aspect ratio.

Perspective Correction: Four Corners and One Matrix Put It Straight

A product shot taken on a desk, phone tilted forward over the box: the vertical edges lean towards each other, the label on the front is a trapezoid, and the top face that is a rectangle in the real world comes out as a wedge. Nothing in the photograph is wrong. The camera was not parallel to the thing it was pointed at.

The same happens to a delivery note photographed instead of scanned, a screen shot off a colleague’s monitor, a sign taken from the pavement, a framed print on a wall. Long edges stay straight, but pairs of edges that are parallel in the world stop being parallel in the file, and the closer edge is always the longer one.

The obvious repairs fail. Rotate the picture and the trapezoid rotates with it. Crop it and you are cutting a rectangle out of a shape that is not one. Stretch it wider and the near edge grows as much as the far edge. WordPress core is honest about the limit: WP_Image_Editor documents resize(), multi_resize(), crop(), rotate() and flip(), and nothing that could do this job.

What it takes to fix perspective distortion in photo files is a different kind of transform and four points to pin it down. The tool below does that in this browser tab. Your file is read through an object URL inside the page: nothing is uploaded, nothing is fetched, no request of any kind is made. The customer address on that delivery note never leaves your machine.

Perspective and keystone corrector

Drag the four corners onto a rectangle that was photographed at an angle and get it back flat, square and in its true proportions. The homography is solved here, the pixels are resampled here, and the picture never leaves this browser tab.

Drop a photograph here, or press Enter to choose one. Nothing is uploaded.

Sample photograph, drawn in this browser.

The photograph, drag the four corners

The corners go clockwise from the top left. Pick one and the arrow keys nudge it a pixel at a time, with shift ten. While you drag, the loupe shows the pixels under the pointer, because a corner you cannot see is a corner you cannot hit.

Straightened

 

 

Target ratio

The automatic estimate is geometry, not a guess: the two vanishing points of the opposite edge pairs are the images of two directions that are at right angles on the real object, and that one fact pins down the focal length and with it the true ratio. It needs perspective to work on. Once a vanishing point sits further than twenty image diagonals from the centre, one pixel of slip at a corner is enough to throw the answer right off, so the tool refuses it and says so instead.

Output
760
The matrix

Source pixels in, output pixels out, normalised so that h₃₃ is one. The resampler never uses it in this direction: for every destination pixel it applies the inverse, built from the adjugate of the same three by three, divides through by w and reads the source between its pixels.


  

That is the same mapping as a CSS transform. Put it on the original photograph with transform-origin: 0 0 and the browser straightens it for you, on the compositor, with no canvas at all.

WunderPaint
The Dynamic Design and Automation Studio
WunderPaint is a layered image editor for your WordPress media library. WunderPaint Studio is the same thing in any browser, free and without an account.

Rotate, crop and scale are the wrong family

Every transform in a normal image editor belongs to the affine family: translate, rotate, scale, shear and combinations of them. An affine map of a plane has six free numbers and one property that matters here above all: parallel lines stay parallel. Two edges that converge in the source converge in the result, whatever you do with crop, rotate and scale.

A camera pointed at a flat object from an angle performs a projective map instead, and that has eight free numbers rather than six. It still keeps straight lines straight, which is why the edges of your box are clean in the photo, but it is allowed to let two parallel lines meet. The point where they meet is the vanishing point, and it is what the two extra numbers carry.

The name for that map is a homography: a 3×3 matrix acting on homogeneous coordinates. Nine entries, but the matrix is defined only up to a common scale factor, so eight are free. Eight unknowns need eight equations, and four point pairs give exactly eight. That is why the interface asks for four corners and not three or five.

Table comparing transform families. Translate, rotate, uniform scale, scale per axis, shear and affine have between one and six free numbers and all keep parallel lines parallel, while a homography has eight free numbers and lets parallel lines converge.

Four corners, eight equations

You drag four numbered handles onto the corners of the rectangle as it appears in the photograph. The tool knows where they should end up: the corners of a clean rectangle in the target ratio. Each source and destination pair gives two linear equations, one from x and one from y, once the projective division is cleared away. Fixing the bottom right entry at 1 removes the free scale factor and leaves eight unknowns.

source (x, y)  ->  destination (u, v)

x*h11 + y*h12 + h13 - u*x*h31 - u*y*h32 = u
x*h21 + y*h22 + h23 - v*x*h31 - v*y*h32 = v

four point pairs  ->  8 rows, 8 unknowns, h33 fixed at 1

That system is solved by Gauss elimination with partial pivoting, and the pivoting is not decoration. Without the row swap the solver divides by an almost zero pivot as soon as two corners sit on one horizontal, the ordinary case of a poster on a level shelf photographed with only a forward tilt. The unpivoted version does not warn you. It returns enormous numbers and an output that flies off the canvas.

The sampling runs backwards

This is the most useful idea in the subject. The naive way to apply the matrix is to walk the source pixels, push each through the homography and paint it where it lands. That is forward mapping, and it is broken: the landing points are fractional and unevenly spaced, so parts of the destination receive several source pixels stacked on each other and other parts receive none. The empty parts are holes, and now you need a second algorithm to fill them.

The correct way runs in the other direction. Walk the destination pixels instead, and apply the inverse matrix to ask where in the source each one came from. Every output pixel is visited once and written once, so no holes and no collisions, and the interpolation happens in the source where the grid is still complete and evenly spaced.

None of that is exclusive to this tool. ImageMagick describes its own distortion operators in the same terms, mapping “the coordinate of each pixel in the destination image to the corresponding location in the source image” and reading the colour there. Its -distort Perspective takes four control point pairs, and GIMP’s Perspective tool works from four corner handles too, though GIMP’s manual notes it “is not actually a perspective tool, as it doesn’t impose perspective rules”. Comparable tools exist. What differs is where the pixels are processed and what the tool tells you.

The inverse matrix comes from the adjugate of the same 3×3, with no need to divide by the determinant: the result is used in homogeneous coordinates and the common factor cancels in the division that follows. That division is the projective part. The matrix gives three numbers, and the source coordinates are the first two divided by the third. When the third is constant you are back to an affine map.

All three numbers are affine along a destination scanline, so each changes by a fixed amount from one pixel to the next: the inner loop adds three constants and does one division instead of recomputing a matrix product, then samples by nearest neighbour, bilinear or Catmull-Rom bicubic. Anything landing outside the source is written fully transparent rather than clamped to the nearest edge pixel, because clamping produces the smeared border streaks that give a bad warp away instantly.

Flow diagram of backward resampling. Each destination pixel passes through the inverse 3x3, the divide by w, and a nearest, bilinear or Catmull-Rom read of the source, with anything landing outside the source written as transparent. Tap counts are 1, 4 and 16, and the drag preview is 420 pixels wide.

The true aspect ratio is hiding in the vanishing points

Here is the question that separates a straightening tool from a guessing one. Four corners tell you the shape of the quadrilateral. They do not tell you whether the original was A4, a square or a 16:9 screen, and if you pick wrong the output is flat, square and still the wrong proportions. Most tools ask you to choose. The geometry can often answer instead.

Extend the two edges that were parallel in the world and they meet at a vanishing point; the other pair gives a second. A vanishing point is the image of a direction rather than of a place, so those two points are the images of two directions that meet at a right angle on the real object. Assume a pinhole camera with square pixels and the principal point at the centre of the frame, back-project both vanishing points, and demand that the two direction vectors have a dot product of zero. That is one equation in one unknown, and the unknown is the square of the focal length.

vanishing points   V1 = (u1, v1)   V2 = (u2, v2)
principal point    (cx, cy) = centre of the frame

f^2 = -( (u1 - cx)*(u2 - cx) + (v1 - cy)*(v2 - cy) )

K = [ f 0 cx ; 0 f cy ; 0 0 1 ]
columns 1 and 2 of  inv(K) * H  ->  the two real side lengths
ratio = |column 1| / |column 2|

With the focal length known the camera matrix is known, and the homography that maps the unit square onto your four corners can be pulled back through it. Its first two columns are then the two side directions scaled by the two real side lengths, so the ratio of their lengths is the aspect ratio of the original. No guessing about paper sizes.

The sample image built into the tool exists to prove the arithmetic closes. It is a 600 by 900 poster projected through a camera whose parameters are known because they were chosen: 22 degrees of pitch, 18 of yaw, focal length 1100 pixels. The estimate hands back exactly those 1100 pixels and a ratio of 1.500. That is the test to ask of any estimator.

When the estimate degenerates, and how you find out

The method has a failure mode, and it is the common case rather than an exotic one. On a nearly frontal shot the converging edges barely converge, the vanishing points run off towards infinity, and the expression for the square of the focal length goes negative. An imaginary focal length is the arithmetic saying the picture does not contain enough perspective to measure perspective with.

Three conditions are tested and named: an imaginary focal length, vanishing points further out than twenty image diagonals, and a quadrilateral that is not a simple one. When one fires, the tool says which, visibly falls back on the fallback ratio you selected (edge lengths by default, or 1:1, 3:2, 4:3, or A series portrait), and marks the result as a fallback in the meta line and in data-fell. A tool that substitutes a guess for a measurement and presents both the same way is worse than one that refuses. The twenty diagonals were measured, not picked: at three degrees of tilt a one pixel slip at a corner still leaves roughly 0.2 percent of error in the ratio, and at two degrees the same arithmetic tips into an imaginary focal length.

Two more limits. Dragging one corner past another turns the quadrilateral into a bow tie, and a self-intersecting quadrilateral is refused outright, with the previous good result left on screen. And the estimate assumes square pixels with the principal point at the centre, so a heavily cropped picture or one shot with a shift lens breaks that assumption invisibly. For those, set the ratio by hand: 1:1, 3:2, 2:3, 4:3, 3:4, A series landscape or portrait, or typed in as 16:9, 16/9 or a plain number.

What it deliberately does not do

A homography maps straight lines to straight lines, and that sets the hard boundary of what four corners can repair. Lens distortion breaks the assumption before you start: the OpenCV calibration documentation puts it in one line, “radial distortion causes straight lines to appear curved”, and models it with the coefficients k1, k2, p1, p2 and k3. Shoot the sign on a wide phone lens and the edges are already bowed. Pin the four corners and they land perfectly while the middle of each edge still bulges. Undistort with a lens profile first, then bring that file here.

The file also has to be one the browser can decode, because the decoding is the browser’s. The MDN guide to image file types for the web lists APNG, AVIF, GIF, JPEG, PNG, SVG and WebP as supported, with BMP, ICO and TIFF as ones to avoid. HEIC is not on that list, which is why a photo copied straight off an iPhone may refuse to open here, and why HEIC uploads hit the same wall in WordPress. Convert to JPEG or PNG first.

Three smaller omissions. Alpha is interpolated straight rather than premultiplied, so a PNG with hard transparent regions can fringe by about a pixel there, which never shows on a photograph. Two copies of the tool on one page are not supported, the documented limit for the whole plugin. And it warps pixels and nothing else: no exposure correction, no removing the shadow your hand cast across the page, no text sharpening, no reading the text at all. There is no fetch, no XHR, no innerHTML, no external script or font and no Math.random, so the whole thing behaves identically offline.

Stretched corners lose sharpness

Straightening evens out the geometry. It cannot even out the information. The far end of the object occupied fewer source pixels than the near end, and afterwards both occupy the same number of output pixels, so the far end has been enlarged and the near end reduced in one pass. Text along the far edge comes back soft, and that softness is real: the detail was never recorded. Catmull-Rom bicubic holds edge contrast better than bilinear, but invents nothing and can overshoot into a light halo. Nearest neighbour is for cases where any blending is wrong.

So shoot as square-on as the shelf allows and fill the frame, so the far edge still gets pixels. Then set the output width slider, 240 to 1600 pixels with a live readout, close to the width you will publish at, because scaling up afterwards is the worst of both worlds and the size question is better settled before export. What the resampler and the export setting actually cost is measurable rather than a matter of taste.

The source is worked on at no more than 1400 pixels on the long side, and while a corner is under the pointer the output drops to 420 pixels wide and four taps so the preview keeps up, with the full pass running again on release. Arrow keys nudge a corner one pixel and shift ten, a loupe follows the handle, and corner snap and the perspective grid switch off when they get in the way.

The matrix, and getting the result into a page

Three things come out: the straightened PNG, the 3×3 in numbers, and the same mapping as a CSS matrix3d. The last is for a warp you want live on an element rather than baked into a file, a mockup sitting at an angle in a hero section for instance. MDN states that the sixteen values of matrix3d() “are described in the column-major order”, which is where most hand written attempts go wrong.

H = [ a b c ; d e f ; g h 1 ]

transform: matrix3d(
  a, d, 0, g,
  b, e, 0, h,
  0, 0, 1, 0,
  c, f, 0, 1
);

Note the direction. That CSS transform is the forward map, source to destination, applied to a live element by the compositor, while the resampler uses its inverse. Confusing the two is the classic reason a CSS experiment and an exported file disagree.

Once the PNG is straight, everything downstream gets simpler. A catalogue in which every box front is a true rectangle crops predictably and sits on a grid without visual wobble, half the work described in making product photos that do not look fake. From there it is an ordinary upload, and the built in image editor handles the crop and scale that follow. To do the crop, the scale and the replacement without leaving the media library, that is what WunderPaint is for.

Four points, eight numbers

This feels unfixable in a normal editor because the editor offers only the affine family while the damage was done by a projective map. Once you see that the missing piece is two extra numbers, and that four corners supply exactly the eight equations that pin them down, the rest is bookkeeping: solve carefully enough that a level shelf does not blow up the pivot, and sample backwards so every output pixel is written once.

The aspect ratio is the part worth being sceptical about in any tool. Recovering it from two vanishing points is real geometry with a real answer, and on a picture with enough tilt it returns the true proportions of an object you never measured. On a nearly frontal shot it collapses, and the only thing separating a trustworthy tool from an untrustworthy one is whether it says so. When you see the fallback marker, either reshoot with more angle or set the ratio yourself, because you know what the object was and the arithmetic does not.

Keep two hard walls in mind before blaming the tool. A bowed edge is lens distortion and needs undistorting first, since no homography straightens a curve. A soft far edge is missing information and no resampler puts it back. Everything between those walls is four handles and a matrix, computed on your own machine, on a file that never went anywhere.

Perspective Correction: Four Corners and One Matrix Put It Straight

Table of Contents

Learn it by building something

Every week one thing you can make the same afternoon, from dynamic templates to 3D type. Written down step by step.

One mail a week, and then it ends.
Unsubscribe in one click.

Print & Craft

From Screen to Paper: What Actually Changes When a Design Gets Printed

Resolution that is not a property of the file, colors that cannot be mixed in ink, and a blade that never lands exactly on the line you drew.

CSS & Front-End

Font Face Generator: The Licence and the Layout Shift

Two things go wrong with web fonts: the licence nobody opened, and the layout that jumps when the font finally arrives. Both answers are already inside the file, in tables you can read in your own browser before you serve a single byte.

Developer Tools

Encoding Forensics: How to Fix Mojibake Like ü

ü is not corruption. It is one umlaut, two UTF-8 bytes, read by a program that believed they were Windows-1252, then saved again so the wrong reading became the content. Here is how to tell which wrong turn your text took, why copied replacement lists only half work, and what to check in the database before you clean anything.

AI Images

AI Product Photos That Do Not Look Fake: Light, Shadow, Perspective

A real product photo on a generated background gives itself away on exactly three axes: light direction, shadow quality and perspective. Here is the physics in plain words, a browser tool that walks you through all three checks on your own composite, and the prompt lines that stop the mismatch happening in the first place.

WordPress Images

WooCommerce Product Image Size: The Three Settings That Decide Everything

WooCommerce shows the same photograph in three places using three different files. Here are the three registered sizes, the cropping option that decides what happens to a mixed range, and why changing a width appears to do nothing.

Developer Tools

Text Cleaner: Getting the Junk Out of Pasted Text

Pasted text carries more than words: Word markup, PDF line breaks, tracking parameters, and a set of characters that render as nothing at all. What each one actually is, why WordPress makes some of it worse, and what to strip.

Download the free WunderPaint Plugin for WordPress

The WunderPaint workspace with the layers panel, adjustment sliders, text style presets and the asset library along the bottom

The Image Editor & Design Studio

Everything described here can be done in the browser, on your own site. The live demo runs the full editor with nothing to install.

Free

Chaos Art

Autonomous painters make one-of-a-kind abstract art in 3D space - gestures, art movements, painterly media, and embeds that paint a new original for every visitor.

Pro

Particle Strokes

Paint with swarms of light: twenty-two movements, a stamp you draw yourself, and curves that give a stroke a shape - the swarm keeps painting for a few seconds after you let go.

Pro

City Diorama

Any place on earth as a miniature you could hold: real streets, water and building footprints raised into a 3D diorama - or wrapped around a sphere as your own tiny planet.

Free

Papercut Art

Layered paper pictures with real depth - a photo sliced along its actual depth into up to twenty layers, parametric landscapes, animals and clouds you can shape, letters with real counters, and a look that runs on three dials.

Pro

3D Earth Studio

A hyperrealistic globe - day and night with city lights, live clouds, atmosphere halo, country borders and highlights, click-to-place markers with flight-route arcs, satellite orbits, seamless rotation video and a live website embed.

Free

Mystic Studio

Turn a birth date into wall art - a real natal chart with houses and aspects, the moon of that night, zodiac and Chinese zodiac posters, numerology cards and a synastry wheel for two, in eight artful themes.

Free

Marble Bath

Marble paper on a virtual water bath - drop, rake and comb real Ebru patterns with gestures, flowers and classic recipes, razor-sharp at any size and re-editable as a layer.

Free

Day Ring

Turn a day into a beautiful circular schedule - colour-coded time blocks as arcs around a 24-hour clock, with concentric rings for overlaps, emoji, templates and a legend.

Free

Code Shot

Turn code into a gorgeous, share-ready image - syntax highlighting, editor themes, window frames and diff highlighting - then drop it into your design as a re-editable layer.

Pro

3D Solar System Studio

Build a date-accurate 3D solar system - real planet positions for any date, photoreal textures and one slider from artistic to true scale - then drop it into your design as an editable layer.

Pro

3D Molecule Studio

Build a real 3D molecule - from a curated library, the periodic table or a SMILES string - then style it, measure it and drop it into your design as an editable layer.

Pro

3D Textile Studio

Drop your design onto cloth that behaves like the material you pick: silk falls soft, felt holds its shape, flag fabric snaps in the wind. Hang it, blow it and drape it, then lay the finished drape back into your document as a picture.

Pro

3D Particle Studio

Point the engine at any layer and it becomes a cloud of particles that keeps its colours, flowing through a sphere, a galaxy or your own outline. Keep the frame you like as a still, or embed the running engine so it keeps moving on your page.

Free

Origami

Put your own picture on the paper and watch that very sheet fold itself into a crane or a box. Every step is a station you can stop at and turn around in 3D, which is exactly where printed diagrams leave you alone.

Pro

3D Flip Studio

A hardcover you can leaf through, a limp magazine, a strewn pile of sheets, a sticker peeling off its backing. The curl is real geometry, so the print never slides across the paper.

Free

Handwriting Fonts

Draw the alphabet here or fill in a printed sheet and photograph it. What comes out is a genuine font family, installed into your site and available in every picker.

Pro

Step Guides

Turn any picture into an instruction. Every mark is pinned to a place in the image, so arrows still point at the right thing after the callout has been dragged somewhere else.

Free

Text Art

One studio, sixteen art types: ASCII and emoji art, brick, dice, cube, sticky-note, LED, ceramic and keycap mosaics, word portraits, text flows, silhouettes, element tiles and more.

Free

Photo Mosaic

The classic photomosaic, computed in your browser: your main image emerges from many media-library photos via true structure matching - never a cheap overlay.

Free

Puzzle Sheets

Generate printable puzzle sheets: word search, mazes in eight shapes, sudoku with unique solutions, criss-cross, cryptograms and number pyramids.