EquiRectangular Projection Help
Hi all,
I am in process of making equirectangular panorama as a part of my project, by following some steps of panoramic Mosaic generation. Until now, I am able to generate panorama when it is wrapped in cylindrical coordinates. But in that, we can't get top and bottom portion. I want full view 360x180 panorama which is possible through spherical coordinates. I have looked in many resources and papers but I didn't find formulas which converts wrap images in those coordinates. Also I have used PTGui, and other commercial software in which they allow to move , rotate an image on sphere and unwrap it.(a.k.a Equirectangular projection), but source code is not available. In the case of libPano which is open source, it is not understandable why they have used specific formulas..
So is there any one, who atleast can give me some hint..
Any kind of help will be appreciated.
Thank you.
Re: EquiRectangular Projection Help
I'm not quite sure what you're asking. Are you having an issue with finding a free stitcher that can create equirectangulars? If so, try the open source package, Hugin. Are you having issues with shooting the coverage for an equirectangular? If so, consider getting a panohead like a Nodal Ninja or Panosaurus that will allow you to take multiple rows, as well as rotate around the no-parallax point to shoot the zenith (straight up) and nadir (straight down) shots.
You actually have to cover the sphere photographically, either by shooting more images, or by using a very wide angle lens. I have a fisheye lens (Sigma 8mm f/3.5 circular) that gives me 180 degree vertical coverage across the frame if my camera is in portrait orientation. I will shoot a zenith and nadir anyway for additional patching material, in case my alignment is off.
http://backup.cambridgeincolour.com/...f17cb352_z.jpg
Note how the last two images are the zenith and nadir shots to do full coverage. I then used PTMac (today, I use PTGui) to stitch together the equirectangular, and I use Photoshop layers and masks to patch in the floor from the handheld zenith shot to cover where the tripod was.
http://backup.cambridgeincolour.com/...595f3ba4_z.jpg
You can't just take a cylindrical pano and make an equirectangular out of it, because you have no polar coverage.
Re: EquiRectangular Projection Help
hey inkista ,
thanks a lot for help. Well, let me explain you a bit more. I am not looking for any free readymade available stitchers. As this is my own project, I am in the way of implementing one on my own. Till date, it is working good with cylinder projection only. And as you said we can't cover zenith/nadir with that projection, I have to use full spherical projection. Now look at the attached images. This has nothing to do with stitching, it just requires a bit of maths related to projections. I gave two images to PTGui, and one can change the projection in the editor window of it. Note that currently I have selected the equirectangular projection. Now see how the photos become curved.
In the pics you uploaded, see the last one. It has got extreme distortion near poles. I need a mathematical formula of that. I want to understand, given any image and its theta,phi angles, how to distort it(as PTGui does).
Steps:
Image in normal projection:
http://i41.tinypic.com/5yu6mg.jpg
Now in equirectangular :
http://i39.tinypic.com/29cxxkp.jpg
Now I moved image a bit upwards:
http://i39.tinypic.com/kb63v4.jpg
Even more:
http://i41.tinypic.com/14xnqk8.jpg
On pole:
http://i39.tinypic.com/2sbae0k.jpg
I want to understand this. Want a mathematical formula or algorithm or code for this.
Re: EquiRectangular Projection Help
hugin and PTGui are based on the panotools set of utilities - panotools is a free, open source collection of utilities, so you can download the code and take a look:
http://panotools.sourceforge.net/
Good luck!
kirk
Re: EquiRectangular Projection Help
Ya i told in my first post that for panotools (as the call the library libPano), i didn't find any documentation about code. They have used some random math function without even mentioning what does it mean. If you find and documentation, pls give me a link..
Re: EquiRectangular Projection Help
Ok, you're in over my head. All I know is that an equirectangular mapping is a simple spherical->cartesian translation of θ -> y, and φ -> x. I assume that just shifting the POV around is basically rotating and remapping the sphere.
Re: EquiRectangular Projection Help
Hello.
I understood that you want to write yet another panoramic image integration program but I don't understand your query. What are you asking for?. A mathematical formula with which meaning?.
If it is the formula used in a specific program then here is a suggestion from the personal experience of your fellow enthusiast programmer (Me): If you can't understand a program's source code then recreating it may help to understand it. However, if you are unable to modify the existing program to fit for a specific task because you don't understand it you will fail short of writing one to do the task from scratch. Search for the reasons than impede to you understanding the existing program and work on these. Informatics and general society would be much better if we follow the attitude of (Paraphrasing Scheme's R5RS Introduction) not working around over our shortcomings but rather addressing the underlying shortcoming than appears to make the reimplementation, bloating feature or otherwise workaround necessary. Maybe you just need to study basic trigonometry.
Quote:
Originally Posted by
inkista
You can't just take a cylindrical pano and make an equirectangular out of it, because you have no polar coverage.
There don't exists a projection named "cylindrical". That's a class of projections. The equirrectangular projection is a cylindrical projection [I assumed Mercator projection was meant and subsequently modified the message when I realized the mistake. The previous paragraph has been preserved as a quote below for consistency purpose]
Quote:
It is possible to transform between these projections, it's just than there won't be full coverage. like with the common perspective adjust function in most image editors. How to deal artistically with the void space depends on the image and the artistic sense of the photographer.
Regards and good luck.
Re: EquiRectangular Projection Help
Quote:
What are you asking for?. A mathematical formula with which meaning?.
For the projection itself. The formula which TELLS me how to DISTORT the given image. In simple term :
a function which takes an image and some other params and give the distorted image(as i have attached).
Quote:
Maybe you just need to study basic trigonometry.
Well, i think i did. But the problem is how to apply that in image processing? Especially in this problem.
Quote:
There don't exists a projection named "cylindrical". That's a class of projections. The equirrectangular projection is a cylindrical projection [I assumed Mercator projection was meant and subsequently modified the message
Exactly , the equirectagular is also called equidistant cylinder. Even mercator will be helpful ..
Re: EquiRectangular Projection Help
Quote:
I assume that just shifting the POV around is basically rotating and remapping the sphere.
Yes that's what i want to do. But how??
Quote:
an equirectangular mapping is a simple spherical->cartesian translation of θ -> y, and φ -> x
Ok then..what is the way to get theta, phi of each pixel from an image?
Re: EquiRectangular Projection Help
Quote:
Originally Posted by
dan19
... Ok then..what is the way to get theta, phi of each pixel from an image?
From the x,y coordinate of the pixel and the dimensions of the equirectangular.
Say, that your equirectangular is 1000x500 pixels.
y=250 is your horizon. y=0 is the south pole. y=500 is the north pole.
x=0=1000 is phi=0, x=500 is phi = 180 degrees = pi (rho) [And you can probably make rho however big you want]
So, my guess is (factoring out rho) theta = (y-y/2)/height * pi/2 and phi= x/width * pi
right? (maybe. My basic math is really weak these days. I haven't done geometry/trig/polar since middle school).
Re: EquiRectangular Projection Help
Re: EquiRectangular Projection Help
Quote:
So, my guess is (factoring out rho) theta = (y-y/2)/height * pi/2 and phi= x/width * pi
Ya that's correct. But that would give theta and phi OF the equirectangular image, isn't it? And that are all varying linearly. I want the theta and phi OF the original image(which is to be projected).
Quote:
(maybe. My basic math is really weak these days. I haven't done geometry/trig/polar since middle school).
No it isn't. Even i thought the same trick.
Re: EquiRectangular Projection Help
This has very good theory. Thanks..
Still wondering, can you find any code or algorithm for applying on images? :confused:
Re: EquiRectangular Projection Help
This video http://www.youtube.com/watch?v=3Ic5ZIf74Ls is explaining what's happening. But isn't there atleast one open source program which just do the distortion ? :confused:
Re: EquiRectangular Projection Help
From: http://www.lroc.asu.edu/data/LRO-L-L...ALOG/DSMAP.CAT
Code:
LABEL_REVISION_NOTE = "Ernest Bowman-Cisneros, 2011-03-08"
RECORD_TYPE = STREAM
SPACECRAFT_NAME = "LUNAR RECONNAISSANCE ORBITER"
TARGET_NAME = "MOON"
OBJECT = DATA_SET_MAP_PROJECTION
DATA_SET_ID = "LRO-L-LROC-5-RDR-V1.0"
OBJECT = DATA_SET_MAP_PROJECTION_INFO
MAP_PROJECTION_TYPE = "EQUIRECTANGULAR"
MAP_PROJECTION_DESC = "
The EQUIRECTANGULAR projection is based on the formula for a
sphere. To eliminate confusion in the IMAGE_MAP_PROJECTION
object we have set all three values, A_AXIS_RADIUS, B_AXIS_RADIUS,
and C_AXIS_RADIUS to the same number, which is R below.
The Equirectangular projection is a simple projection providing a
linear relationship between the geographic coordinates of latitude
and longitude and the Cartesian space of the map. In continuous
form, the equations relating map coordinates (x, y) to geographic
coordinates (Lat, Lon) are:
x = R * (Lon - LonP) * COS(LatP)
y = R * Lat
where LonP is the center longitude of the map projection,
LatP is the center latitude of the projection at which scale
is given, and R the radius of the body at the center latitude.
For the Moon R is assumed to be 1734.4 km.
The inverse formulas for Lat and Lon from x and y position in the
projection are:
Lat = y / R
Lon = LonP + x / (R * COS(LatP))
The Conversion from (x, y) map coordinates to image array
coordinates (sample, line) is standard for all map projections and
is:
x = (Sample - S0) * Scale
y = (-L0 - Line) * Scale
where Scale is the map resolution in km/pixel (located at the
center planetocentric latitude of the projection). Line and
Sample are the coordinates of the image array, and line (L0)
and sample offsets (S0) are the respective image coordinate
displacements from pixel (1,1) to the origin of the projection
(x,y) = (0,0). Please note, pixel (1,1) is spatially located
in the upper-left corner of the image array.
The equations from (x, y) to (Sample, Line) are:
Sample = x / Scale + S0 + 1
Line = -y / Scale - L0 + 1
The equation from (Sample, Line) to (Lat, Lon) is:
Lat = y / R
y = (1 - L0 - Line) * Scale
Lat = (1 - L0 - Line) * Scale / R
Lon = LonP + x / (R * COS(LatP))
x = (Sample - S0 - 1) * Scale
Lon = LonP + (Sample - S0 - 1) * Scale/ (R * COS(LatP))
The keywords corresponding to the Equirectangular projection
parameters are located in the IMAGE_MAP_PROJECTION object found
in the PDS labels. The keywords for each equation parameter are
shown below:
LonP | CENTER_LONGITUDE
LatP | CENTER_LATITUDE
L0 | LINE_PROJECTION_OFFSET
S0 | SAMPLE_PROJECTION_OFFSET
Scale | MAP_SCALE
R | A_AXIS_RADIUS (same as B_AXIS_RADIUS and
| C_AXIS_RADIUS)
"
END_OBJECT = DATA_SET_MAP_PROJECTION_INFO
OBJECT = DATA_SET_MAP_PROJECTION_INFO
MAP_PROJECTION_TYPE = "POLAR STEREOGRAPHIC"
MAP_PROJECTION_DESC = "
The Polar Stereographic projection, used for observations
acquired at higher latitudes, is ideally suited for observations
near the poles as shape and scale distortion are minimized. The
LROC derived products in Polar Stereographic projection use the
ellipsoid form of the equations.
In continuous form, the spherical equations relating map
coordinates (x, y) to planetocentric coordinates (Lat, Lon)
are:
North Polar Stereographic
x = 2 * Rp * TAN(Pi / 4 - Lat / 2) * SIN(Lon - LonP)
y = -2 * Rp * TAN(Pi / 4 - Lat / 2) * COS(Lon - LonP)
South Polar Stereographic
x = 2 * Rp * TAN(Pi / 4 + Lat / 2) * SIN(Lon - LonP)
y = 2 * Rp * TAN(Pi / 4 + Lat / 2) * COS(Lon - LonP)
Where LonP is the central longitude, LatP is the latitude of
true scale and is always 90 or -90, and Rp is the polar radius of
the Moon or 1,737.4 km.
The spherical inverse formulas for Lat and Lon from X and Y
position in the image array are:
Lat = ARCSIN[COS(C) * SIN(LatP) + y * SIN(C) * COS(LatP) / P]
North Polar Stereographic
Lon = LonP + ARCTAN[x / (-y)]
South Polar Stereographic
Lon = LonP + ARCTAN[x / y]
where:
P = SQRT(x^2 + y^2)
C = 2 * ARCTAN(P / 2 * Rp)
recall:
x = (Sample - S0 - 1) * Scale
y = (1 - L0 - Line) * Scale
The keywords corresponding to the equation parameters for the
Polar Stereographic projection are located in the
IMAGE_MAP_PROJECTION object found in the PDS labels. The
keywords for each equation parameter are shown below.
LonP | CENTER_LONGITUDE
LatP | CENTER_LATITUDE
L0 | LINE_PROJECTION_OFFSET
S0 | SAMPLE_PROJECTION_OFFSET
Scale | MAP_SCALE
R | A_AXIS_RADIUS (same as B_AXIS_RADIUS and
| C_AXIS_RADIUS)
"
END_OBJECT = DATA_SET_MAP_PROJECTION_INFO
OBJECT = DATA_SET_MAP_PROJECTION_INFO
MAP_PROJECTION_TYPE = "ORTHOGRAPHIC"
MAP_PROJECTION_DESC = "
The ORTHOGRAPHIC projection preserves neither area nor angle and
is a perspective projection from an infinite distance. Is also
referred to a view from space.
In continuous form, the spherical equations relating map coordinates
(x, y) to planetocentric geographic coordinates (Lat, Lon) are:
x = R * COS(Lat) * SIN(Lon - LonP)
y = R * [(COS(LatP) * SIN(Lat)) - (SIN(LatP) * COS(Lat) *
COS(Lon - LonP))]
where LonP is the center longitude of the map projection, LatP is the
center latitude of the projection at which the scale is given, and R
is the radius of the body at the center latitude. For the Moon, R is
given as 1737.4 km.
For the Orthographic projection, there are three special instances
where the equation for solving for y is modified, while finding x is
still found by the first equation:
1. North Polar Orthographic, where LatP = 90:
y = -R * COS(Lat) * COS(Lon - LonP)
2. South Polar Orthographic, where LatP = -90:
y = R * COS(Lat) * COS(Lon - LonP)
3. Equatorial Orthographic, where LatP = 0:
y = R * SIN(Lat)
The spherical inverse formulas to derive Lat and Lon from a given x
and y position in the projection are:
Lat = ARCSIN[COS(C) * SIN(LatP) + (y * SIN(C) * COS(LatP)/P)]
Lon = LonP + ARCTAN * [ (x * SIN(C)) / ((P * COS(LatP) * COS(C))
- (y * SIN(LatP) * SIN(C))]
If LatP = 90:
Lon = LonP + ARCTAN[x / (-y)]
If LatP = -90:
Lon = LonP + ARCTAN[x / y]
where:
P = SQRT(x2 + y2)
C = ARCSIN(P/R)
Standard map coordinates (x, y) to image array coordinates (Sample,
Line):
x = (Sample - S0 - 1) * Scale
y = (1 - L0 - Line) * Scale
where scale is...
NOTE: if Scale is negative, the point value is NULL (the feature
is beyond the curvature of the body)
The keywords corresponding to the Orthographic projection...
LonP | CENTER_LONGITUDE
LatP | CENTER_LATITUDE
L0 | LINE_PROJECTION_OFFSET
S0 | SAMPLE_PROJECTION_OFFSET
Scale | MAP_SCALE
R | A_AXIS_RADIUS (same as B_AXIS_RADIUS and C_AXIS_RADIUS)
"
END_OBJECT = DATA_SET_MAP_PROJECTION_INFO
OBJECT = DS_MAP_PROJECTION_REF_INFO
REFERENCE_KEY_ID = "SNYDER1987"
END_OBJECT = DS_MAP_PROJECTION_REF_INFO
END_OBJECT = DATA_SET_MAP_PROJECTION
END
Re: EquiRectangular Projection Help
And this is from the libpano source, in the file perspect.c
Code:
/* Panorama_Tools - Generate, Edit and Convert Panoramic Images
Copyright (C) 1998,1999 - Helmut Dersch der@fh-furtwangen.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*------------------------------------------------------------*/
#include "filter.h"
// -------------------------- Functions ------------------------------------------------------
void perspective(TrformStr *TrPtr, pPrefs *prefs)
{
double v[3]; // auxilliary vector
double points_per_degree;
double mt[3][3];
double alpha, beta, gammar; // Angles in rad
double x_off, y_off, d;
double a;
pt_int32 destwidth, destheight;
fDesc fD;
void *params[4]; // Parameters for perspective control functions
params[0] = (void*)mt;
params[1] = (void*)&d;
params[2] = (void*)&x_off;
params[3] = (void*)&y_off;
// Set destination image parameters
destwidth = prefs->width;
destheight = prefs->height;
if( destwidth <= 0 || destheight <= 0 )
{
TrPtr->success = 0;
PrintError( "Zero Destination Image Size" );
return;
}
if( SetDestImage(TrPtr, destwidth, destheight) != 0 )
{
TrPtr->success = 0;
PrintError( "Not enough Memory.");
return;
}
// Set parameters for perspective transformation
a = DEG_TO_RAD( prefs->hfov );
alpha = DEG_TO_RAD( prefs->y_beta );
beta = DEG_TO_RAD( prefs->x_alpha );
gammar = DEG_TO_RAD( prefs->gamma );
fD.func =(trfn)NULL;
switch(prefs->format)
{
case _rectilinear:
if( a >= PI )
{
TrPtr->success = 0;
PrintError("HFOV must be smaller than 180 degrees");
return;
}
d = TrPtr->src->width / ( 2.0 * tan( a/2.0 ) );
if( prefs->unit_is_cart )
{
alpha = atan( (prefs->y_beta - TrPtr->src->height/2.0 ) / d );
beta = - atan( (prefs->x_alpha - TrPtr->src->width/2.0 ) / d );
}
fD.func = persp_rect;
break;
case _spherical_tp:
d = TrPtr->src->width / a;
if( prefs->unit_is_cart )
{
points_per_degree = ((double) TrPtr->src->width) / (a * 360 / (2 * PI)) ;
alpha = ((TrPtr->src->height/2.0 - prefs->y_beta)/ points_per_degree) * 2 * PI / 360;
beta = -((TrPtr->src->width/2.0 - prefs->x_alpha)/ points_per_degree) * 2 * PI / 360;
}
fD.func = persp_sphere;
break;
}
SetMatrix( alpha, beta, gammar , mt, 1 );
// Offset
v[0] = 0.0;
v[1] = 0.0;
v[2] = d;
matrix_mult( mt, v );
x_off = v[0]*d/v[2];
y_off = v[1]*d/v[2];
// Do transformation
if( fD.func != NULL)
{
fD.param = params;
//transFormEx( TrPtr, &fD, &fD, 0, 1 );
transForm( TrPtr, &fD, 0 );
}
else
TrPtr->success = 0;
if( TrPtr->success == 0 && ! (TrPtr->mode & _destSupplied)) // Moved here
myfree( (void**)TrPtr->dest->data );
}
void SetPerspectiveDefaults( pPrefs *pP )
{
pP->magic = 40;
pP->format = _rectilinear;
pP->hfov = 60;
pP->x_alpha = 0.0;
pP->y_beta = 0.0;
pP->gamma = 0.0;
pP->unit_is_cart = FALSE;
pP->width = 500;
pP->height = 300;
}
Re: EquiRectangular Projection Help
And this from the libpano source, remap.c:
Code:
/* Panorama_Tools - Generate, Edit and Convert Panoramic Images
Copyright (C) 1998,1999 - Helmut Dersch der@fh-furtwangen.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*------------------------------------------------------------*/
#include "filter.h"
void remap(TrformStr *TrPtr, rPrefs *r_prefs)
{
fDesc fD; // remapping function
double vars[3]; // variables required for calculation
// vars[0] = distance d
// vars[1]
// vars[2]
double a,b; // horizontal/vertical field of view in 'rad'
int destwidth=0, destheight=0;
fD.param = (void*) vars;
fD.func = (trfn)NULL;
// Check for inconsistent values (should be extended!)
if( r_prefs->hfov <= 0.0 )
{
TrPtr->success = 0;
PrintError("Parameter Error");
return;
}
// Set destination image parameters and parameters for remapping
a = DEG_TO_RAD( r_prefs->hfov );
switch(r_prefs->from)
{
case _rectilinear:
if( a >= PI )
{
TrPtr->success = 0;
PrintError("Wrong FOV: Must be smaller than 180 degrees");
return;
}
vars[0] = TrPtr->src->width / ( 2.0 * tan( a/2.0 ) );
switch(r_prefs->to)
{
case _rectilinear: TrPtr->success = 0;
PrintError("Same Mapping!");
return;
break;
case _panorama :
destheight = TrPtr->src->height;
destwidth = (int)(a * vars[0] + 0.5);
fD.func = rect_pano;
break;
case _equirectangular:
destheight = (int)(2.0 * vars[0] * atan( TrPtr->src->height/(2*vars[0]) ) + 0.5);
destwidth = (int)(a * vars[0] + 0.5);
fD.func = rect_erect;
break;
case _spherical_cp:TrPtr->success = 0;
PrintError("Use Fisheye Horizontal and Perspective");
return;
break;
case _spherical_tp:
destheight = (int)(2.0 * vars[0] * atan( TrPtr->src->height/(2*vars[0]) ) + 0.5);
destwidth = (int)(a * vars[0] + 0.5);
fD.func = rect_sphere_tp;
break;
case _mirror:TrPtr->success = 0;
PrintError("Sorry, not yet available");
return;
break;
default: break;
}
break;
case _panorama:
vars[0] = TrPtr->src->width / a;
switch(r_prefs->to)
{
case _rectilinear:
if( a >= PI )
{
TrPtr->success = 0;
PrintError("Wrong FOV: Must be smaller than 180 degrees");
return;
}
destheight = TrPtr->src->height;
destwidth = (int)(2.0 * tan( a/2.0 ) * vars[0] + 0.5);
fD.func = pano_rect;
break;
case _panorama : TrPtr->success = 0;
PrintError("Same Mapping!");
return;
break;
case _equirectangular:
destheight = (int)(2 * vars[0] * atan( TrPtr->src->height/ (2*vars[0]) ));
destwidth = TrPtr->src->width;
fD.func = pano_erect;
break;
case _spherical_cp:
TrPtr->success = 0;
PrintError("Sorry, not yet available");
return;
break;
case _spherical_tp:
destheight = TrPtr->src->width ;//2 * vars[0] * atan( TrPtr->src->height/ (2*vars[0]) );
destwidth = TrPtr->src->width;
fD.func = pano_sphere_tp;
break;
case _mirror:TrPtr->success = 0;
PrintError("Sorry, not yet available");
return;
break;
default: break;
}
break;
case _equirectangular:
vars[0] = TrPtr->src->width / a;
b = TrPtr->src->height/ vars[0];
switch(r_prefs->to)
{
case _rectilinear:
if( a >= PI || b >= PI )
{
TrPtr->success = 0;
PrintError("Wrong FOV: Must be smaller than 180 degrees");
return;
}
destheight = (int)(2 * vars[0] * tan( TrPtr->src->height/(2*vars[0]) ));
destwidth = (int)(2 * vars[0] * tan( TrPtr->src->width/(2*vars[0]) ));
fD.func = erect_rect;
break;
case _panorama :
if( b >= PI )
{
TrPtr->success = 0;
PrintError("Wrong VFOV: Must be smaller than 180 degrees");
return;
}
destheight = (int)(2 * vars[0] * tan( TrPtr->src->height/(2*vars[0]) ));
destwidth = TrPtr->src->width;
fD.func = erect_pano;
break;
case _equirectangular:TrPtr->success = 0;
PrintError("Same Mapping!");
return;
break;
case _spherical_cp:
destwidth = 2 * TrPtr->src->height;
destheight = 2 * TrPtr->src->height;
vars[1] = TrPtr->src->height/2; // vars[1] is midpoint
fD.func = erect_sphere_cp;
break;
case _spherical_tp:
destwidth = TrPtr->src->width;
destheight = TrPtr->src->width;
fD.func = erect_sphere_tp;
break;
case _mirror:TrPtr->success = 0;
PrintError("Sorry, not yet available");
return;
break;
default: break;
}
break;
case _spherical_cp:
if( r_prefs->hfov > MAX_FISHEYE_FOV && r_prefs->vfov > MAX_FISHEYE_FOV ){
TrPtr->success = 0;
PrintError("Fisheye lens processing limited to fov <= %lg", MAX_FISHEYE_FOV);
return;
}
vars[0] = TrPtr->src->width / a;
switch(r_prefs->to)
{
case _rectilinear:TrPtr->success = 0;
PrintError("Sorry, not yet available");
return;
break;
case _panorama :
if(r_prefs->vfov >= 180.0 )
{
TrPtr->success = 0;
PrintError("Wrong VFOV: Must be smaller than 180 degrees");
return;
}
destheight = (int)(PI * vars[0] * tan(r_prefs->vfov * PI / 360.0));
destwidth = (int)(PI * vars[0] * PI);
fD.func = sphere_cp_pano;
break;
case _equirectangular:
destheight = (int)((TrPtr->src->width > TrPtr->src->height ?
TrPtr->src->width/2: TrPtr->src->height/2) * PI / 2.0);
destwidth = (int)(vars[0] * PI * PI);
vars[1] = destheight / 2;
fD.func = sphere_cp_erect;
break;
case _spherical_cp:TrPtr->success = 0;
PrintError("Same Mapping!");
return;
break;
case _spherical_tp:TrPtr->success = 0;
PrintError("Use tool perspective.");
return;
break;
case _mirror:
vars[1] = TrPtr->src->width / (2 * sin(a/4.0)) ; // Radius of mirror
destwidth = TrPtr->src->width ;
destheight = TrPtr->src->height ;
fD.func = sphere_cp_mirror;
break;
default: break;
}
break;
case _spherical_tp:
if( r_prefs->hfov > MAX_FISHEYE_FOV && r_prefs->vfov > MAX_FISHEYE_FOV ){
TrPtr->success = 0;
PrintError("Fisheye lens processing limited to fov <= %lg", MAX_FISHEYE_FOV);
return;
}
vars[0] = TrPtr->src->width / a;
b = TrPtr->src->height / vars[0];
switch(r_prefs->to)
{
case _rectilinear:
if( a >= PI || b >= PI )
{
TrPtr->success = 0;
PrintError("Wrong FOV: Must be smaller than 180 degrees");
return;
}
destheight = (int)(2.0 * vars[0] * tan( TrPtr->src->height / (2.0*vars[0]) ) + 0.5);
destwidth = (int)(2.0 * tan( a/2.0 ) * vars[0] + 0.5);
fD.func = sphere_tp_rect;
break;
case _panorama :
if( b >= PI )
{
TrPtr->success = 0;
PrintError("Wrong VFOV: Must be smaller than 180 degrees");
return;
}
destheight = (int)(2.0 * vars[0] * tan( TrPtr->src->height / (2.0*vars[0]) ) + 0.5);
destwidth = TrPtr->src->width;
fD.func = sphere_tp_pano;
break;
case _equirectangular:
destheight = TrPtr->src->height ;
destwidth = TrPtr->src->width;
vars[1] = destheight / 2;
fD.func = sphere_tp_erect;
break;
case _spherical_cp:TrPtr->success = 0;
PrintError("Use tool perspective.");
return;
break;
case _spherical_tp:TrPtr->success = 0;
PrintError( "Same Mapping!");
return;
break;
case _mirror:TrPtr->success = 0;
PrintError( "Sorry, not yet available");
return;
break;
default: break;
}
break;
case _mirror:
vars[1] = TrPtr->src->width / (2 * sin(a/4.0)) ; // Radius of mirror
vars[0] = TrPtr->src->width / a;
switch(r_prefs->to)
{
case _rectilinear:TrPtr->success = 0;
PrintError("Sorry, not yet available");
return;
break;
case _panorama :
if(r_prefs->vfov >= 180.0 )
{
TrPtr->success = 0;
PrintError("Wrong VFOV: Must be smaller than 180 degrees");
return;
}
destheight = (int)(PI * vars[0] * tan(r_prefs->vfov * PI / 360.0));
destwidth = (int)(PI * vars[0] * PI);
fD.func = mirror_pano;
break;
case _equirectangular:
destwidth = (int)(vars[0] * PI * PI);
destheight = (int)(PI * vars[0] * a / 4.0);
vars[2] = destheight / 2.0;
fD.func = mirror_erect;
break;
case _spherical_cp:
destwidth = TrPtr->src->width ;
destheight = TrPtr->src->height ;
fD.func = mirror_sphere_cp;
break;
case _spherical_tp:TrPtr->success = 0;
PrintError( "Sorry, not yet available");
return;
break;
case _mirror:TrPtr->success = 0;
PrintError( "Same Mapping!");
return;
break;
default: break;
}
break;
default: break;
}
if( SetDestImage(TrPtr, destwidth, destheight) != 0 )
{
TrPtr->success = 0;
PrintError( "Not enough Memory.");
return;
}
// Do transformation
if( fD.func != NULL)
{
transFormEx( TrPtr, &fD, &fD, 0, 1 );
//transForm( TrPtr, &fD, 0 );
}
else
TrPtr->success = 0;
if( TrPtr->success == 0 && ! (TrPtr->mode & _destSupplied)) // Moved here
myfree( (void**)TrPtr->dest->data );
}
void SetRemapDefaults( rPrefs *rP )
{
rP->magic = 30; // Magic number for file validity check
rP->from = _rectilinear;
rP->to = _panorama;
rP->hfov = 60.0;
rP->vfov = 60.0;
}
Re: EquiRectangular Projection Help
hey kirkt , first of all thanks a lot for helping..
I have came across those before. The first one you posted, I saw that a few days ago,
but i didnt understand why they have defined following relationship :
Code:
The Equirectangular projection is a simple projection providing a
linear relationship between the geographic coordinates of latitude
and longitude and the Cartesian space of the map. In continuous
form, the equations relating map coordinates (x, y) to geographic
coordinates (Lat, Lon) are:
x = R * (Lon - LonP) * COS(LatP)
y = R * Lat
because it should be linear relation from lat/lon to x,y then why introduced the cos factor?
and for last two i have seen over 10 times, and +1 as you posted in hope that I understand something but all in all, it seems very cryptic to me. I don't think so the perspect.c is responsible for the equirectangular projection(i may be wrong). Remap.c attracted a lot of my attention but the lines
Code:
double vars[3]; // variables required for calculation
// vars[0] = distance d
// vars[1]
// vars[2]
and..
Code:
destheight = (int)(2.0 * vars[0] * atan( TrPtr->src->height/(2*vars[0]) ) + 0.5);
destwidth = (int)(a * vars[0] + 0.5);
were beyond my understanding. Can you? and the biggest nonsense thing i believe is why in the hell didn't they include enough comments so that the code doesn't look alien to others !:mad:
Re: EquiRectangular Projection Help
Hi there,
I'd like to write or find a javascript or php converter: Equirectangular to cube faces.
Any help?
Thanks
Re: EquiRectangular Projection Help
As you climb up the Lat the Long will change according to Cos(Lat)