[MathMap] Lambert conformal conic projection

473 views
Skip to first unread message

Edgar Bonet

unread,
Apr 20, 2010, 4:01:43 PM4/20/10
to mat...@googlegroups.com
Hello fellow MathMap users!

Here I am again with a new defishing filter.

As many people playing with defishing filters, I noticed that the
stereographic and the Mercator projections work well for remapping
fisheye pictures. These are both traditional mapping projections that
share a common property: they are conformal, which means that they have
no local distorsion. That's why they tend to give pleasing mappings.

Now, there is a third traditional conformal mapping of the sphere: the
Lambert conformal conic projection (I'll call it LCC). At first I
thought that LCC was not very useful for photography... until I took a
picture that was better served by this than by any oher projection I
know about.

Attached is an exampe usage. It is not the picture that motivated my
coding, but it is a good example: a low-angle fisheye shot. I would like
to remap it in a way that straightens the verticals. What options do I
have?

- The rectilinear mapping works, of course, but I want to avoid it
because the corners of the image end up stretched beyond reason, to
the point where one may run into resolution problems.

- The Mercator projection does also the job. However, since the
verticals are now vertical, the low-angle perpective is lost. Also,
the picture area acquires a weird shape, which makes cropping
difficult, and there is also significant stretching of the top of the
image, which may bring back the resolution problems.

- I could use the Mercator projection without correcting for the pitch
of the camera, then I get the so called "oblique Mercator". This fixes
the problem about the weird image shape and the strong stretching.
However, the verticals are not straight any more but acquire an S
shape.

- Finally, the LCC projection is quite a good solution for this kind of
problem: the verticals are straight, the low-angle effet is preserved,
and the picture is nowhere highly stretched. Actually, the remapped
picture looks quite similar to the original, so I see LCC as the
smallest modification that straightens the verticals and undoes the
fisheye peripheral compression (by being conformal).

Here is the MathMap code of my filter:

# Fisheye to Lambert conformal conic
filter fish2conic(image in,
float pitch: -90-90 (0),
float roll: -90-90 (0),
float rendered_pitch: -90-90 (0),
float zoom: 0.6-1 (0.8),
float y_offset: -1-1 (0),
bool grid
)
f = 10.5/23.6*W;
pitch_r = deg2rad(pitch);
shifted = xy:[x, y-y_offset*Y] /f/zoom;
lambda_r = deg2rad(rendered_pitch);
sl = sin(lambda_r);
tl = 2*tan((pi/2-lambda_r)/2);
conic = ri:[-shifted[1], shifted[0]];
conic = conic / (1+sin(lambda_r))*2;
if abs(sl) < .00001 then
stereo = exp(conic/tl)*(1-sl/2*(conic/tl)^2)*tl;
else
stereo = (conic*sl/tl+1)^(1/sl)*tl;
end;
colat = 2*atan(abs(stereo)/2);
long = arg(stereo);
xx = sin(colat) * sin(long);
y1 = cos(colat);
z1 = sin(colat) * cos(long);
yy = y1*cos(pitch_r) - z1*sin(pitch_r);
zz = z1*cos(pitch_r) + y1*sin(pitch_r);
phi = atan(yy, xx);
theta = atan(sqrt(xx*xx+yy*yy), zz);
out = in(ra:[1.476*f*sin(.713*theta), phi+deg2rad(roll)]);
if grid && (x/X+1)*4%1 < .02 then
out = (out + rgbColor(1, 1, 0)) / 2;
end;
out
end

The code is tuned for my Nikon 10.5 DX, which claims to be equal-area
but is not quite so. I found empirically that it is well fit by the
mapping

r = 1.476*f*sin(.713*theta).

You may have to tune it for your own fisheye by changing the fisheye
mapping (the line "out = in(ra[...]);") or by using

r = 2*f*sin(.5*theta)

if your fisheye does follow the equal-area mapping.

And here is the "manual" for the filter:

- Set the grid on.
- Adjust the pitch and roll in order to get the verticals vertical. Use
the grid lines as guides. You may play with zoom and y_offset in order
to better see the relevant parts of your image.
- Set the grid off.
- Adjust the rendered_pitch in order to restore the low-angle
perspective. Set rendered_pitch = pitch if you want to get close to
the original perspective.
- Adjust zoom and y_offset in order to minimize the subsequent cropping.

As a side note, if you keep rendered_pitch at zero you get the Mercator
mapping (or oblique Mercator if the camera pitch is not corrected for).
That's because Mercator is the limit of LCC when the principal parallel
goes to the equator. For writing the code I used the fact that LCC can
be derived from the stereographic projection by using a complex power
function, as pointed out here:

http://www.quadibloc.com/maps/mco0301.htm

Regards,

Edgar.

--
You received this message because you are subscribed to the Google Groups "MathMap" group.
To post to this group, send email to mat...@googlegroups.com.
To unsubscribe from this group, send email to mathmap+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mathmap?hl=en.

books-fisheye.jpg
books-remapped.jpg

Tom Rathborne

unread,
Jun 12, 2010, 8:44:00 AM6/12/10
to mat...@googlegroups.com
Hi Edgar,

Thanks for the Lambert defishing filter!

I removed the 'roll' parameter and replaced it with lerp(t,-180,180)

Then applied it to an adjusted version of:
http://kilo.aceldama.com/stuff/nikon950b/dscn0523.jpg

and cropped and scaled, here is the result:
http://kilo.aceldama.com/stuff/sun-spin.gif

Lots of fun, thanks again!!

Cheers,

Tom

--
-- Tom Rathborne -------------------------------------- Chief Fractal Hacker --
It is not because things are difficult that we do not dare,
it is because we do not dare that they are difficult.
-- Marcus Annaeus Seneca

Reply all
Reply to author
Forward
0 new messages