| Attachment | Size |
|---|---|
| 5.61 KB | |
| 1.23 KB |
Turn this:

…into this:

…using the “EZ Perspective” filter, now available at Filters → Distorts → EZ Perspective… – get ez-perspective.py now!
Particularly well-suited for the needs of photographers seeking to correct perspective, but flexible enough to be used by all those wishing to add perspective to an otherwise flat scene.
Demo video by Mahvin.
Installation :: Usage :: Use cases :: Tricks
Future plans :: Similar tools :: Technical details :: Batch processing :: Closing notes
ez-perspective.py.zipez-perspective.py.py file executable (on Linux and Mac OS X), via chmod +x ez-perspective.py (can also do by right-clicking and changing “Properties”)Trouble?
If you’re having trouble:
.pySome general tutorials on perspective correction: Perspective correction – PanoTools & Perspective Correction In Photoshop – Keystoning.
\/ or /\ and use left/right to fix horizontal lines not being parallel: > or <. (And use rotate to rotate.) To get a feel for this, take photos of a window when tilting up, tilting down, swinging left, swinging right, and rotating clockwise/counter-clockwise, and then correct them.(Ctrl-Z, Ctrl-Y) and re-run the filter via Ctrl-Shft-F.But wait, there’s more!
Actually, there isn’t. This is a specialized tool for easily correcting or changing perspective, just like it says on the tin, and that’s all it does.
Main desiderata is to have previewing, which makes tweaking perspective much easier. This requires building the GUI manually, using the full Python gimpplugin library, rather than using the pre-packaged one from gimpfu; it’s do-able, but will take a little time.
Also nice would be to automatically read EFL from Exif, rather than having to key it in. This can’t easily be done currently (Exif information is not available to plug-ins, as far as I can tell), though I plan to hack in something (using exiftool, if available).
“Hmm…,” you say, “but can’t I achieve the same using existing tools, like the (suggestively named) Perspective tool (Tool → Perspective, Shft-P), or perhaps the ‘Map Object – Plane’ filter (Filters → Map → Map Object… → Plane)?”
Well, no.
These are both excellent and powerful tools, but they, and everything else I found discussed under “perspective” (search) do not actually do the desired perspective transforms. If these (or other) tools suit your needs, please use them, but they didn’t satisfy mine, and, if you read on, you, too, may come to share my cravings, and want a new tool. Fortunately, I’ve written one.
Simply, correcting perspective is a very common photographic task – like image rotation – and so you want a specialized tool for it. Further, it has hidden subtleties (elaborated below, in “Technical details”), which mean that a general tool is unlikely to provide the desired behavior.
Turning to the specific tools: the term “perspective tool”, while suggestive, is a misnomer. It is actually a “projective transformation” tool, and can do perspective transforms, but much else besides, and its transforms are almost always not simply changes of perspective. For minor changes, the error is slight, and not terribly objectionable, and many people advocate using this tool (or corresponding ones in other programs) to correct perspective.
Most often advocated is to fix perspective (say, from a shot that is tilted up) by simply stretching the top (e.g., here). The problem is that when you correct perspective, you also need to stretch vertically (or horizontally for left/right perspective), and if you don’t, the result is squat. Here is the result of simply stretching the top, without any vertical stretching (marked as incorrect):

Notice that it is squatter than the correct version; this is most visibly an error as shapes that should be circles are instead ovals.
Further, even if you want to stretch, how much should you stretch? For any angle (and focal length) there’s a single correct amount, mathematically determined, which is difficult to eyeball. Fortunately, we have computers that can do the math for us, as EZ Perspective does. It makes it, if you’ll pardon, “EZ PZ”. Lastly, you may wish a tool where you enter angles, rather than moving corners by mouse, as in the rotation tool. The perspective tool is very powerful and intuitive, but both overkill and a bit fiddly for simply fixing perspective.
“Map Object – Plane” may appear to do the same thing, but it rotates the image, rather than the camera. This filter serves a different purpose – it uses an image as “wallpaper” on some surface. The easiest way to see that it does not do a perspective change is to rotate Y by 30° – the resulting perspective is compressed. In fact, if you rotate by 90°, the plane disappears, while if you actually change perspective by 90° (or, more realistically, by 80–85°), you still have a usable scene, albeit with heavy perspective, corresponding to shooting across (almost parallel to) a surface. More simply, Map Object rotates the image plane so that it is at an angle to the rendering plane, while changing perspective corresponds to projecting an image between parallel planes.
For the mathematically-minded… These are all “as far as I can determine” – if there are any errors or you’ve thoughts or references, please feel free to contact me.
Formally, what this tool does is a “camera transform” (or perhaps more properly, an inverse camera transform, followed by a camera transform) – it assumes that the center of the scene is some distance z* away, but the camera is aimed at an angle, and then changes that angle, keeping the center of the scene at the same distance. (Formally, this is PSO(3), acting on the plane given by z=z*.) The distance is why the 35 mm Equivalent Focal Length is necessary: the effect of changing angle depends on the distance – it determines both the relative scale of stretching (e.g., if tilting, how much vertical stretching) and the scale of angles. The easiest way to see this is to use a very short EFL on a photo taken with a longer EFL (e.g., use 10 mm for the example picture; actually taken with 89 mm) – the resulting corrected image will be too squat, and the correction angle keyed in will significantly understate the actual correct. Simply, tilting wide-angle lenses doesn’t stretch as much, and 1° change is a bigger change with a wide-angle lens than with a telephoto lens. As a detail, the EFL here refers to the diagonal EFL (based on diagonal angle of view), which is the most common convention (some use horizontal).
The rotations are done using the zyx convention for Euler angles (or more properly, Tait–Bryan angles), which can be interpeted as “rotate about the extrinsic axes (axes of the scene) in the order x, y, z (up/down tilt, left/right swing, rotation twist), or about the intrinsic axes (axes of the camera) in the order z, y, x.” This seems the most natural order – how would you line up a shot? This is also why applying the filter twice does not simply add angles – it corresponds to z′y′x′zyx (6 rotations in sequence), which is not the same as (z′+z)(y′+y)(x′+x) because the rotation group is not commutative (order of rotations matters).
Note that these camera transforms only have 6 degrees of freedom (it’s the Euclidean space group) – 3 rotations, 3 movements (2 dimensions of shifting the image, 1 dimension of scaling the image). Our concern are the 3 rotations, but the shifts and scaling show up subtly. The projective linear group of the plane, PGL(3) (all transforms that preserve lines, possibly going out to infinity), has 3×3–1 = 8 dimensions; note that the perspective tool has 8 degrees of freedom = 4 points × 2 dimensions/point, and hence is (a top-dimensional subset of) the full projective linear group. Examples of projective transforms that are not perspective are:
It’s really hard to stay on a 6-dimensional space in 8 dimensions (it’s like staying on a 1-dimensional curve in 3 dimensions), which is why output from the perspective tool is almost never an actual perspective transform, and makes formal the fact that it’s hard to eyeball the right height fix. (It’s slightly subtler – different focal lengths add a 7th dimension, so it’s a bit easier to get a transform that’s a perspective transform, but likely for the wrong lens.) Further, only 3 of the dimensions correspond to rotations – the other 3 correspond to shifting and scaling, so unless you’re careful, the transformed image will be larger or smaller, and shifted: staying on a 3-dimensional space in 8 dimensions is trickier yet. For example, the usual “correct perspective by just stretching the top of an image” (say, by 5%) stretches the image horizontally by an average of 2.5%; to avoid stretching you actually would need to stretch the top by 2.5% and shrink the bottom by 2.5%. EZ Perspective corrects for these, as discussed below.
Finally, two subtleties of projective transforms: shifting and scaling. Projective transforms (the matrices of the rotations) move the center of an image, and change the scale. This tool corrects for these by moving the center back to the center and adjusting scale to minimize distortions. This later is a bit tricky – projective transforms change scale differently in the x and y dimensions (and by a different amount in each row and column), so when changing the up/down tilt, we preserve the width of the center row, and correspondingly for left/right swing (preserve center column height). This is generally what you want; can be further customized by specifying where the “center” is, though I’ll add that later.
Further, changing the angle makes the distances that get closer to the camera grow, while those that get further shrink, so the former center of the image is no longer the center of the transformed image (even if it doesn’t move, there’re still more pixels on one side than on the other). This is inevitable, but changes the effect of the composition, and is a subtlety to be aware of.
You can also use EZ Perspective non-interactively, for batch processing, particularly if you have many files with known perspective, or wish to apply automated distortion. Because non-interactive use of Python-Fu plugins can be a little tricky, I’ve written a wrapper function to simplify it, and given an example script. See the below ez-batch-script-SAMPLE.py file for how to do this; this will require some manual fiddling on your part. Please:
Lastly, the photo (corrected by 40% tilt and 0.3% clockwise rotation, at 89 mm EFL, following pincushion correction) is the former logo of Bowl and Board (hence the shape: a bowl on a board), a delightful housewares store in Cambridge, Mass., now sadly closed.
Hope this tool proves useful – enjoy, and happy Gimping!
Comments
Re: preview
This is a great tool, but would really be excellent with a preview option. Exif import would be even better.
Great work so far!
Thanks!
Thanks for the kind words, Dai Ma, and I look forward to making this even better!
Best,
Nils von Barth
Thanks very much for the
Thanks very much for the plug-in and the excellent tutorial.
Long time ago I did analogue B&W had my own darkroom.
Correcting perspective I did by tilting the paper.
Gerard.
No problem
Hi Gerard,
Thanks for the kind words and reminder of history! (Film? What’s that?) Hope this is a bit easier than developing in the darkroom, though I’m sure that has a certain fun.
Best,
Nils von Barth
Not working on windows
This doesn't seem to be working on windows (XP Pro SP3) with GIMP 2.6.8, Python 2.5.2.
The file is in the right location with the right file name. Other python plug-ins are working, so it's not the install. I've also tried changing the path to #!/usr/bin/env python and converting the encoding to ANSI to no avail.
Any help would be appreciated, as this looks to be incredibly useful
yes not working on windows
maybe because it require something as "math" " gimpfu" and "gettext" that may be not installed on Win or not were expected by the script
at least if i understand correctly this lines of the script
################################################
"from gimpfu import *
from math import pi, sin, cos, sqrt
# Localization (l10n)
#
# use with _("foo") around all strings, to indicate “translatableâ€
import gettext
locale_directory = gimp.locale_directory
gettext.install("gimp20-template", locale_directory, unicode=True)"
##################################################
anyway the script doesn't show up at least not in the Filters/Distort menu
Sorry i can't help to fix , because i have no idea if "gimpfu" is a standard component of gimp and were the script expect to find "gettext"and "math"...
############################################
PS math seems to be a component of openoffice (i have openoffice installed but that doesn't seems to help )
gimpfu should be present if gimp was installed with python support
gettext should be needed only to translate in other languages , so should be not strictly needed ..but maybe is the main problem (that or in a failure to locate "math"on a windows style path...more few windows users will have it since openoffice is not installed in windows by default
Working on both for me
I have it installed on both my Win 7 and Vista machines, and its working for me.
http://www.youtube.com/watch?v=2MCPARFBfnQ (Vista machine)
Check your extension for the plug-in, because when I downloaded it, it had a numerical value after the .py extension.
Works for me on Windows XP, Mac (OS X 10.4), Linux
Thanks for your feedback all, and thanks for the video Mahvin!
Just tried it on Windows, Mac OS X, and Linux (Debian etch, which I develop on), and it worked on all of them (once Python was working on Windows; Gimp 2.6 on Windows and OS X, Gimp 2.4 on Debian). I’ll see if I can figure out what’s causing problems.
PhotoComiX, thanks for your detailed analysis; all the libraries I use are standard libraries:
gimpfuis part of Gimp Python,mathis basic Python (you know, square roots and all), andgettextis the basic internationalization (i18n) library.I’ve made a version without i18n, in case that’s causing the problem – y’all might try it, if you’re having trouble: ez-perspective-no-i18n.py
As Mahvin notes, you have to remove the
.txtand make sure the extension is.py– perhaps you’re already doing this, but it’s necessary due to current registry upload code.Hope this helps get it working!
Got it
Apparently something in my python install was corrupt, because after a re-install of Python, Pycairo, Pygobject, and Pygtk it works :)
Yay!
Excellent – thanks for the feedback, and glad it now works for everyone. (Hope that next time you don’t have to reinstall Windows and reboot 7 times for it to work.)
Best,
Nils von Barth
Pages