Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to flatten a series of fisheye images by remapping them to a rectinlinear projection.

To achieve this, I need to be able to remap the pixels of the image using fisheye correction formulas for the x-, and y-coordinates. How can I achieve this? I have found this question and this question but I wonder how to use this for fisheye correction.

So far I've tried to use ImageTransformation for this, but I can't get the function to work properly.

  f[pt_] := With[{s = {.5, .5}},
  Module[{rd, polarcoor, ru, newcoor},
   rd = Norm[pt - s]^2/Norm[s];
   polarcoor = 
    CoordinateTransform[{"Cartesian" -> "Polar", 2}, (pt - s)];
   ru = 1*Tan[2*ArcSin[((polarcoor[[1]])/(2*1))]];
   CoordinateTransform["Polar" -> "Cartesian", {ru, polarcoor[[2]]}]

This should first translate the image coordinates to polar coordinates, then calculate the new r (ru=r undistorted), and than translate these back to cartesian coordinates. The ru = 1*Tan[2*ArcSin[((polarcoor[[1]])/(2*1))]] is based on the above links, with a random value chosen as f. It fi

I get an error message, saying the function doesn't map. Anyone have an idea how to fix this and any further suggestions on how to improve the code?

Example fisheye image

Update 2 22-10-2013 Changed the code to:

image = Import[""];
r[pt_] := Module[{rd, ru, polarcoor, a},
  rd = Norm[pt];
  ru = *Transformation formula* 
  a = ArcTan @@ (pt);
  ru {Cos[a], Sin[a]}

Using ru = Sqrt[rd]; ImageTransformation[image, r, DataRange -> {{-1, 1}, {-1, 1}}] gives enter image description here

Using ru = ArcTan[rd]; ImageTransformation[image, r, DataRange -> {{-2, 2}, {-2, 2}}] gives enter image description here

Both look like a step in the right direction, with straightened lines, but I got them by trial-and-error so I don't know the correctness.

share|improve this question
your function must always return a position. Your CoordinateTransform[]s are failing for some values ("incompatible with the coordinate assumptions of the specified coordinate chart") – cormullion Oct 21 '13 at 15:39
Seems to work if you evaluate f symbolically, e.g. g[{x_, y_}] = f[{x, y}]; ImageTransformation[image, g] – Simon Woods Oct 21 '13 at 17:32
re your latest update - try restarting your kernel, it doesn't misbehave here. – cormullion Oct 22 '13 at 10:03
@cormullion: Still not working here. Strange. – ErikP Oct 22 '13 at 10:12

It seems to me that your radial remapping is working okay, but the original image appears to have an asymmetric distortion, in that the vertical lines of the buildings converge towards a point which is slightly up from the centre of the image. I think it will be necessary to correct for that before doing the radial remapping. Here's a simple attempt to do the correction.

image = Import[""] ~ImagePad~ -7;

f[c_][{x_, y_}] := Module[{θ, ϕ},
  ϕ = ArcTan[x, y];
  θ = π/2 Sqrt[x^2 + y^2];
  c (1 - Sin[θ]) + 2 θ/π {Cos[ϕ], Sin[ϕ]}]

ImageTransformation[image, f[{0, 0.2}], 
 DataRange -> {{-1, 1}, {-1, 1}}, PlotRange -> {{-1, 1}, {-1, 1}}]

enter image description here

I think this is an improvement, though far from perfect. Of course it all comes down to knowing the form of the distortion.

Original answer

I misunderstood the aim of the question and provided a transformation which unrolls the fisheye image into a panorama. I will leave it here as it attracted a good number of upvotes so I assume it is of interest.

f[x0_, y0_][{th_, r_}] := (1 - 2 r/Pi) ({Sin[th], Cos[th]} - {x0, y0}) + {x0, y0}

ImageTransformation[image, f[0, 0.2], 
 DataRange -> {{-1, 1}, {-1, 1}}, PlotRange -> {{0, 2 Pi}, {0, Pi/2}}]

enter image description here

share|improve this answer
Different way than I've been thinking (see update): For fish-eye undistortion, the radius from image centre to a pixel must be corrected. So I've tried to find that radius (by getting polar coordinates), apply a function to it and than translate the new polar coordinates back to Cartesian. Not getting it to work so far though. – ErikP Oct 22 '13 at 9:32
I am not looking for a way to make panorama images, which is basically what you have achieved. Looks nice though! – ErikP Oct 22 '13 at 14:10
@ErikP, sorry - I misunderstood the aim of the remapping. This must be the highest number of upvotes I've ever had for an answer which utterly fails to answer the question! – Simon Woods Oct 22 '13 at 19:31
no problem, but do you have any ideas on how to solve the question, or give my current solution a nudge in the right direction? – ErikP Oct 23 '13 at 8:14
@ErikP, I'll have another look. The asymmetry of the distortion makes it more complicated than it otherwise would be... – Simon Woods Oct 23 '13 at 9:06

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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