iCub-main
Loading...
Searching...
No Matches
spherical_projection.cpp
Go to the documentation of this file.
1// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2
3/*
4 * Copyright (C) 2007 Alex Bernardino, ISR-IST
5 * Permission is granted to copy, distribute, and/or modify this program
6 * under the terms of the GNU General Public License, version 2 or any
7 * later version published by the Free Software Foundation.
8 *
9 * A copy of the license can be found at
10 * http://www.robotcub.org/icub/license/gpl.txt
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details
16*/
17
18
19#include <iCub/spherical_projection.h>
20
21/*
22Computes spherical projection parameters, from pinhole projection parameters.
23Considers possible radial distortion in the pinhole model.
24WARNING: The function do not validate input parameters. These should be checked previously (see check_sp_params).
25*/
26void compute_sp_params(int input_lines, int input_cols,
27 int output_lines, int output_cols,
28 double fx, double fy,
29 double cx, double cy,
30 double k1, double k2,
31 double p1, double p2,
32 double *fa, double *fe,
33 double *ca, double *ce)
34{
35 double max_azimuth = atan((input_cols-1-cx)/fx);
36 double min_azimuth = atan(-cx/fx);
37 double max_elevation = atan((input_lines-1-cy)/fy);
38 double min_elevation = atan(-cy/fy);
39 *fa = output_cols/(max_azimuth-min_azimuth);
40 *fe = output_lines/(max_elevation-min_elevation);
41 *ca = -min_azimuth*(*fa);
42 *ce = -min_elevation*(*fe);
43}
44
45/*
46Checks validity of spherical projection input parameters.
47*/
48bool check_sp_params(int input_lines, int input_cols,
49 int output_lines, int output_cols,
50 double fx, double fy,
51 double cx, double cy,
52 double k1, double k2,
53 double p1, double p2,
54 float *mapx, float *mapy)
55{
56 if(input_lines <= 1) return false;
57 if(input_cols <= 1) return false;
58 if(output_lines <= 1) return false;
59 if(output_cols <= 1) return false;
60 if(fx <= 0) return false;
61 if(fy <= 0) return false;
62 if(mapx == 0) return false;
63 if(mapy == 0) return false;
64 return true;
65}
66
67/* Computes the warping map for spherical projection.
68 To actually perform the image spherical projection, the computed map
69 (mapx, mapy) must be used in conjuction with opencv funtion cvRemap.
70*/
71bool compute_sp_map(int input_lines, int input_cols,
72 int output_lines, int output_cols,
73 double fx, double fy,
74 double cx, double cy,
75 double k1, double k2,
76 double p1, double p2,
77 float *mapx, float *mapy)
78{
79 double fa, fe, ca, ce, a, e, x, y, r2, xd, yd;
80
81 if(!check_sp_params(input_lines, input_cols, output_lines, output_cols,
82 fx, fy, cx, cy, k1, k2, p1, p2, mapx, mapy))
83 return false;
84
85 compute_sp_params(input_lines, input_cols, output_lines, output_cols,
86 fx, fy, cx, cy, k1, k2, p1, p2,
87 &fa, &fe, &ca, &ce);
88 int i, j;
89 for(i=0;i<output_lines;i++)
90 {
91 for(j=0;j<output_cols;j++)
92 {
93 a=(j-ca)/fa;
94 e=(i-ce)/fe;
95 x=tan(a);
96 y=tan(e);
97 r2 = x*x+y*y;
98 xd = x*(1+k1*r2+k2*r2*r2)+2*p1*x*y+p2*(r2+2*x*x);
99 yd = y*(1+k1*r2+k2*r2*r2)+p1*(r2+2*y*y)+2*p2*x*y;
100 *mapx++ = (float)(fx*xd+cx);
101 *mapy++ = (float)(fy*yd+cy);
102 }
103 }
104 return true;
105}
106
107/* Computes the warping map for egosphere projection.
108 To actually perform the image projection, the computed map
109 (mapx, mapy) must be used in conjuction with opencv funtion cvRemap.
110
111 Assumes iCub's specific reference frames:
112 - World Reference: X axis vertical pointing up
113 Y axis horizontal pointing backward
114 Z axis horizontal pointing right
115
116 - Camera Reference: X axis aligned with optical axis, pointing forward
117 Y axis aligned with image plane pointing right(increasing column index)
118 Z axis aligned with image plane pointing down (increasing line index)
119
120*/
121bool compute_icub_egosp_map( int input_lines, int input_cols,
122 int output_lines, int output_cols,
123 double fx, double fy,
124 double cx, double cy,
125 double *R, //camera to world rotation matrix
126 float *mapx, float *mapy)
127{
128 // converts to intuitive reference frames:
129 /*
130
131 - World Reference: X axis horizontal pointing front
132 Y axis horizontal pointing left
133 Z axis vertical pointing up
134
135 - Camera Reference: X axis aligned with image plane pointing right(increasing column index)
136 Y axis aligned with image plane pointing down (increasing line index)
137 Z axis aligned with optical axis, pointing forward
138 */
139
140 double Rt[9];
141 Rt[0] = -R[4];
142 Rt[1] = -R[7];
143 Rt[2] = R[1];
144 Rt[3] = -R[5];
145 Rt[4] = -R[8];
146 Rt[5] = R[2];
147 Rt[6] = -R[3];
148 Rt[7] = -R[6];
149 Rt[8] = R[0];
150 compute_egosp_map(input_lines, input_cols, output_lines, output_cols, fx, fy, cx, cy, Rt, mapx, mapy);
151 return true;
152}
153
154
155/* Computes the warping map for egosphere projection.
156 To actually perform the image projection, the computed map
157 (mapx, mapy) must be used in conjuction with opencv funtion cvRemap.
158
159 Assumes the following reference frames:
160
161 - World Reference: X axis horizontal pointing front
162 Y axis horizontal pointing left
163 Z axis vertical pointing up
164
165 - Camera Reference: X axis aligned with image plane pointing right(increasing column index)
166 Y axis aligned with image plane pointing down (increasing line index)
167 Z axis aligned with optical axis, pointing forward
168
169*/
170bool compute_egosp_map( int input_lines, int input_cols,
171 int output_lines, int output_cols,
172 double fx, double fy,
173 double cx, double cy,
174 double *R, //world to camera rotation matrix
175 float *mapx, float *mapy)
176{
177 double flongitude, flatitude, clongitude, clatitude, longitude, latitude, x, y;
178 double Xworld,Yworld,Zworld,Xcamera,Ycamera,Zcamera;
179
180 clongitude = output_cols/2;
181 clatitude = output_lines/2;
182 flongitude = output_cols/2/3.141529;
183 flatitude = output_lines/3.141529;
184 int i, j;
185 for(i=0;i<output_lines;i++)
186 {
187 for(j=0;j<output_cols;j++)
188 {
189 latitude=-(i-clatitude)/flatitude;
190 longitude=-(j-clongitude)/flongitude;
191 //world coordinates x,y,z
192 Xworld = cos(longitude)*cos(latitude);
193 Yworld = sin(longitude)*cos(latitude);
194 Zworld = sin(latitude);
195 // convert to camera frame
196 Xcamera= R[0]*Xworld+R[1]*Yworld+R[2]*Zworld;
197 Ycamera= R[3]*Xworld+R[4]*Yworld+R[5]*Zworld;
198 Zcamera= R[6]*Xworld+R[7]*Yworld+R[8]*Zworld;
199 //compute the image projection
200 if(Zcamera > 0)
201 {
202 x = Xcamera/Zcamera;
203 y = Ycamera/Zcamera;
204 *mapx++ = (float)(x*fx+cx);
205 *mapy++ = (float)(y*fy+cy);
206 }
207 else
208 {
209 *mapx++ = -1;
210 *mapy++ = -1;
211 }
212 }
213 }
214 return true;
215}
bool compute_sp_map(int input_lines, int input_cols, int output_lines, int output_cols, double fx, double fy, double cx, double cy, double k1, double k2, double p1, double p2, float *mapx, float *mapy)
bool compute_icub_egosp_map(int input_lines, int input_cols, int output_lines, int output_cols, double fx, double fy, double cx, double cy, double *R, float *mapx, float *mapy)
void compute_sp_params(int input_lines, int input_cols, int output_lines, int output_cols, double fx, double fy, double cx, double cy, double k1, double k2, double p1, double p2, double *fa, double *fe, double *ca, double *ce)
bool compute_egosp_map(int input_lines, int input_cols, int output_lines, int output_cols, double fx, double fy, double cx, double cy, double *R, float *mapx, float *mapy)
bool check_sp_params(int input_lines, int input_cols, int output_lines, int output_cols, double fx, double fy, double cx, double cy, double k1, double k2, double p1, double p2, float *mapx, float *mapy)