I've been researching image warping algorithms lately and haven't found many comprehensive references. That said, there are of course code snippets from GIMP, jhlabs.com, and imagemagick.org but none of these explain the mathematics behind the process. This stackoverflow post gives a very nice and concise example of the bulge warp effect, but it also lacks detailed explanation. Here is the meat of the math: Suppose your image coordinates go from 0 to 1.

If you define:

r = Sqrt[(x - .5)^2 + (y - .5)^2]
a = ArcTan[x - .5, y - .5]
rn = r^2.5/.5 

/* NB: arctan is not really necessary since Cos[a] = (x - .5)/r 
and Sin[a] = (y - .5)/r

And then remap your pixels according to:

x -> rn*Cos[a] + .5 
y -> rn*Sin[a] + .5  


enter image description here

So the question is, what exactly mathematically is going on here? Why does this produce the circular bulge warp? If I wanted the bulge to expand in, say, a triangular pattern, or perhaps with a bias of weighted points rather than equally in all directions, how would I change the trigonometry functions (if at all - a constraint over the given circular pattern might make more sense)?


The code takes each pixel location $(x,y)$, shifts it relative to the image center (0.5,0.5), converts it to polar form $(r,a)$ (so that $x-0.5=r \cos a, y-0.5= r \sin a$) and then maps the point to a new polar point $(\hat{r},a)$ where $$ \hat{r} = 2 r^{2.5} $$ (My $\hat{r}$ is called rn in your code.) Finally, the point is shifted by 0.5 horizontally and vertically.

This results in an increased radius, with a greater increase for larger radii: this gives the bulging effect. Note that the center of the image is fixed: the center (0.5,0.5) gets shifted to (0,0) which has a radius of r=0, so $r'=0$. Pixels are "pushed out" away from the center of the image in a non-linear way.

Having $r'=kr$, for a positive constant $k$, for example, would result in a simple scaling of the image about the center.

(Note $2r^{2.5}>r$ for $r>0.6299...$.)

The circular nature you mention is a result of all points at the same distance from the center being treated the same way: $\hat{r}$ only depends on $r$.

To get other kinds of distortion, try making $\hat{r}$ dependent on $r$ and other variables, like $a$, $x$, or $y$. This will get you some non-circular distortions.

  • $\begingroup$ aha, polar coordinate system was the buzz-phrase I've been looking for it seems! Thanks very much! Two additional questions: 1. where does rn=2r^(2.5) come from? 2. What is the order of operations from the original post where rn is given as rn=2r^2.5/0.5? I assume the division by 0.5 effects the horizontal and vertical shift you mentioned, but is the actual order 2r^(2.5/0.5) or (2r^2.5)/0.5? The first form gives 'nicer' numbers since 2.5/0.5=5... $\endgroup$ – CCJ Dec 28 '12 at 18:37
  • 1
    $\begingroup$ @CCJ The original post gives rn=r^2.5/0.5 which is interpreted as rn=(r^2.5)/0.5; I wrote it as the equivalent rn=2r^2.5=2(r^2.5). There are no "nice" numbers here, regardless of the exponent. As to where this comes from, I imagine this was just found experimentally. Anything of the form $\hat{r} = a r^b$ will give a bulging/shrinking distortion. You can play around with $a$ and $b$ until you get the effect you like. $\endgroup$ – Matthew Conroy Dec 28 '12 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.