33 #ifndef GSLAM_CAMERA_H 34 #define GSLAM_CAMERA_H 42 #include "pmmintrin.h" 53 virtual std::string CameraType()
const{
return "NoCamera";}
54 virtual bool isValid()
const{
return false;}
57 virtual std::vector<double> getParameters()
const{
return std::vector<double>();}
59 virtual bool applyScale(
double scale=0.5){
return false;}
60 virtual std::string info()
const;
74 virtual std::string CameraType()
const{
return "Ideal";}
75 virtual bool isValid()
const{
return true;}
76 virtual Point2d Project(
const Point3d& p3d)
const{
double z_inv=1./p3d.z;
return Point2d(p3d.x*z_inv,p3d.y*z_inv);}
78 virtual std::vector<double> getParameters()
const{
return {(double)w,(
double)h};}
87 CameraPinhole(
int _w,
int _h,
double _fx,
double _fy,
double _cx,
double _cy)
88 :
CameraImpl(_w,_h),fx(_fx),fy(_fy),cx(_cx),cy(_cy),fx_inv(0),fy_inv(0)
91 virtual std::string CameraType()
const{
return "PinHole";}
92 virtual bool isValid()
const{
return w>0&&h>0&&fx!=0&&fy!=0;}
95 virtual std::vector<double> getParameters()
const{
return {(double)w,(
double)h,fx,fy,cx,cy};}
97 virtual bool applyScale(
double scale=0.5);
99 double fx,fy,cx,cy,fx_inv,fy_inv;
102 int refreshParaments(){
if(isValid()){fx_inv=1./fx;fy_inv=1./fy;
103 return 0;}
else return -1;}
123 CameraATAN(
int _w,
int _h,
double _fx,
double _fy,
double _cx,
double _cy,
double _d);
125 virtual std::string CameraType()
const{
return "ATAN";}
126 virtual bool isValid()
const{
return w>0&&h>0&&fx!=0&&fy!=0;}
129 virtual std::vector<double> getParameters()
const{
return {(double)w,(
double)h,fx,fy,cx,cy,d};}
131 virtual bool applyScale(
double scale=0.5);
133 double fx,fy,cx,cy,d,fx_inv,fy_inv;
134 double tan2w,d_inv,tan2w_inv;
136 virtual int refreshParaments();
137 bool& UseDistortion(){
return useDistortion;}
155 CameraOpenCV():fx(0),fy(0),cx(0),cy(0),fx_inv(0),fy_inv(0){}
157 double Fx,
double Fy,
double Cx,
double Cy,
158 double K1,
double K2,
double P1,
double P2,
double K3)
159 :
CameraImpl(Width,Height),fx(Fx),fy(Fy),cx(Cx),cy(Cy),
160 k1(K1),k2(K2),p1(P1),p2(P2),k3(K3){refreshParaments();}
162 virtual std::string CameraType()
const{
return "OpenCV";}
163 virtual bool isValid()
const{
return w>0&&h>0&&fx!=0&&fy!=0;}
166 virtual std::vector<double> getParameters()
const{
return {(double)w,(
double)h,fx,fy,cx,cy,k1,k2,p1,p2,k3};}
168 virtual bool applyScale(
double scale=0.5);
169 double fx,fy,cx,cy,fx_inv,fy_inv,
172 int refreshParaments();
178 Camera(
const std::shared_ptr<CameraImpl>& Impl=std::shared_ptr<CameraImpl>(
new CameraImpl()));
179 Camera(
const std::vector<double>& paras);
181 std::string CameraType()
const{
return impl->CameraType();}
182 std::string info()
const{
return impl->info();}
183 bool isValid()
const{
return impl->isValid();}
184 int width()
const{
return impl->w;}
185 int height()
const{
return impl->h;}
187 Point2d Project(
const Point3d& p3d)
const{
return impl->Project(p3d);}
188 Point2d Project(
const double x,
const double y,
const double z)
const {
return Project(
Point3d(x, y, z)); }
190 Point3d UnProject(
const Point2d& p2d)
const{
return impl->UnProject(p2d);}
191 Point3d UnProject(
const double x,
const double y)
const {
return UnProject(
Point2d(x, y)); }
193 std::vector<double> getParameters()
const{
return impl->getParameters();}
195 bool applyScale(
double scale=0.5){
return impl->applyScale(scale);}
196 Camera estimatePinHoleCamera(
void)
const;
199 std::shared_ptr<CameraImpl> impl;
202 inline std::string CameraImpl::info()
const{
203 std::stringstream sst;
204 sst<<CameraType()<<
":[";
205 std::vector<double> paras=getParameters();
206 for(
size_t i=0;i<paras.size();i++)
207 sst<<paras[i]<<((i+1==paras.size())?
"]":
",");
211 inline bool CameraPinhole::applyScale(
double scale) { w=(int32_t)(w*scale); h=(int32_t)(h*scale); fx*=scale;fy*=scale;cx*=scale;cy*=scale; refreshParaments();
return true; }
218 __m128d xy = _mm_setr_pd(p3d.x,p3d.y);
219 xy=_mm_add_pd(_mm_setr_pd(cx,cy),_mm_mul_pd(xy,(__m128d){fx,fy}));
224 double z_inv=1./p3d.z;
225 return Point2d(fx*z_inv*p3d.x+cx,fy*z_inv*p3d.y+cy);
231 return Point2d(fx*p3d.x+cx,fy*p3d.y+cy);
235 double z_inv=1./p3d.z;
236 return Point2d(fx*z_inv*p3d.x+cx,fy*z_inv*p3d.y+cy);
244 return Point3d((p2d.x-cx)*fx_inv,(p2d.y-cy)*fy_inv,1.);
247 inline CameraATAN::CameraATAN():fx(0),fy(0),cx(0),cy(0),d(0),fx_inv(0),fy_inv(0){}
249 inline CameraATAN::CameraATAN(
int _w,
int _h,
double _fx,
double _fy,
double _cx,
double _cy,
double _d)
250 :
CameraImpl(_w,_h),fx(_fx),fy(_fy),cx(_cx),cy(_cy),d(_d),fx_inv(0),fy_inv(0)
251 {refreshParaments();}
253 inline int CameraATAN::refreshParaments()
256 std::cout<<
"Camera not valid!Info:"<<info()<<std::endl;
260 fx*=w;fy*=h;cx*=w;cy*=h;
262 if(fx!=0) fx_inv=1./fx;
else return -1;
263 if(fy!=0) fy_inv=1./fy;
else return -2;
266 tan2w = 2.0 * tan(d / 2.0);
275 useDistortion =
false;
280 inline bool CameraATAN::applyScale(
double scale)
281 { w=(int32_t)(w*scale); h=(int32_t)(h*scale); fx*=scale; fy*=scale; cx*=scale; cy*=scale; refreshParaments();
return true;}
285 if(p3d.z<=0)
return Point2d(-1,-1);
290 __m128d xy=(__m128d){p3d.x,p3d.y};
293 xy=_mm_sub_pd(xy,(__m128d){p3d.z,p3d.z});
295 __m128d xy2=_mm_mul_pd(xy,xy);
297 xy2=_mm_hadd_pd(xy2,xy2);
298 xy2=_mm_sqrt_pd(xy2);
300 if(r < 0.001 || d == 0.0)
303 r=(d_inv* atan(r * tan2w) / r);
304 xy=_mm_mul_pd((__m128d){fx,fy},xy);
305 xy=_mm_mul_pd(xy,(__m128d){r,r});
306 xy=_mm_add_pd(xy,(__m128d){cx,cy});
313 __m128d xy = _mm_setr_pd(p3d.x,p3d.y);
314 xy=_mm_add_pd(_mm_setr_pd(cx,cy),_mm_mul_pd(xy,(__m128d){fx,fy}));
319 double z_inv=1./p3d.z;
320 return Point2d(fx*z_inv*p3d.x+cx,fy*z_inv*p3d.y+cy);
326 double X=p3d.x,Y=p3d.y;
329 double z_inv=1./p3d.z;
332 double r= sqrt(X*X+Y*Y);
333 if(r < 0.001 || d == 0.0)
336 r=(d_inv* atan(r * tan2w) / r);
338 return Point2d(cx + fx * r * X,cy + fy * r * Y);
344 return Point2d(fx*p3d.x+cx,fy*p3d.y+cy);
348 double z_inv=1./p3d.z;
349 return Point2d(fx*z_inv*p3d.x+cx,fy*z_inv*p3d.y+cy);
360 Point3d result((p2d.x-cx)*fx_inv,(p2d.y-cy)*fy_inv,1.);
361 double r = sqrt(result.x*result.x+result.y*result.y);
363 if(d != 0.0&& r >0.01)
365 r = ( tan(r * d)*tan2w_inv )/r;
371 else return Point3d((p2d.x-cx)*fx_inv,(p2d.y-cy)*fy_inv,1.);
374 inline bool CameraOpenCV::applyScale(
double scale){ w=(int32_t)(w*scale); h=(int32_t)(h*scale); fx*=scale;fy*=scale;cx*=scale;cy*=scale; refreshParaments();
return true;}
376 inline int CameraOpenCV::refreshParaments()
379 std::cout<<
"Camera not valid!Info:"<<info()<<std::endl;
381 if(fx!=0) fx_inv=1./fx;
else return -1;
382 if(fy!=0) fy_inv=1./fy;
else return -2;
388 if(p3d.z<=0)
return Point2d(-1,-1);
389 double X=p3d.x,Y=p3d.y;
392 double z_inv=1./p3d.z;
396 double r2,r4,r6,X1,Y1,X2,Y2,xy2;
403 X1= X*(1.+k1*r2 + k2*r4+k3*r6) + xy2*p1 + p2*(r2 + 2.0*X2);
404 Y1= Y*(1.+k1*r2 + k2*r4+k3*r6) + xy2*p2 + p1*(r2 + 2.0*Y2);
406 return Point2d(cx + fx * X1,cy + fy * Y1);
411 double x = (p2d.x - cx)*fx_inv;
412 double y = (p2d.y - cy)*fy_inv;
418 for(
int j = 0; j < 5; j++ )
420 double r2 = x*x + y*y;
421 double icdist = (1)/(1 + ((k3*r2 + k2)*r2 + k1)*r2);
422 double deltaX = 2*p1*x*y + p2*(r2 + 2*x*x);
423 double deltaY = p1*(r2 + 2*y*y) + 2*p2*x*y;
424 x = (x0 - deltaX)*icdist;
425 y = (y0 - deltaY)*icdist;
431 inline Camera::Camera(
const std::shared_ptr<CameraImpl>& Impl):impl(Impl)
435 inline Camera::Camera(
const std::vector<double> &p)
438 if(p.size()==2) cam=
new CameraIdeal((
int)p[0],(int)p[1]);
439 else if(p.size()==6) cam=
new CameraPinhole((
int)p[0],(int)p[1],p[2],p[3],p[4],p[5]);
440 else if(p.size()==7) cam=
new CameraATAN((
int)p[0],(int)p[1],p[2],p[3],p[4],p[5],p[6]);
441 else if(p.size()==11) cam=
new CameraOpenCV((
int)p[0],(int)p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10]);
443 impl=std::shared_ptr<CameraImpl>(cam);
446 inline Camera Camera::estimatePinHoleCamera()
const 448 if( CameraType() ==
"PinHole" || CameraType() ==
"Ideal" ) {
458 double xl_max = -99999, xr_min = 99999, yt_max = -99999, yb_min = 99999;
461 for(iy=0; iy<ih; iy++) {
463 if( p.x > xl_max ) xl_max = p.x;
467 for(iy=0; iy<ih; iy++) {
469 if( p.x < xr_min ) xr_min = p.x;
473 for(ix=0; ix<iw; ix++) {
475 if( p.y > yt_max ) yt_max = p.y;
479 for(ix=0; ix<iw; ix++) {
481 if( p.y < yb_min ) yb_min = p.y;
485 double _fx, _fy, _cx, _cy;
487 xx = fabs(xl_max);
if( xx > fabs(xr_min) ) xx = fabs(xr_min);
488 yy = fabs(yt_max);
if( yy > fabs(yb_min) ) yy = fabs(yb_min);
495 if( _fx < _fy ) _fx = _fy;
499 std::shared_ptr<CameraImpl> impl_result = std::shared_ptr<CameraImpl>(camera);
501 return Camera(impl_result);
Camera model used by OpenCV Project: r^2= X^2+Y^2; X1= X*(1+k1*r^2 + k2*r^4+k3*r^6) + 2*p1*XY + p2*(r...
Definition: Camera.h:152
Pinhole model (x y)^T=(fx*X/Z+cx,fy*Y/Z+cy)^T.
Definition: Camera.h:83
Identity pinhole camera,fx=fy=1&&cx=cy=0 (x y)^T=(fx*X/Z+cx,fy*Y/Z+cy)^T.
Definition: Camera.h:69
Camera described in PTAM(alse called ANTA camera), measurement: , z=1 plane: (X,Y)^T Project: |x|=|cx...
Definition: Camera.h:119