You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

383 lines
14 KiB

////////////////////////////////////////////////////////////////////////////
// File: DataInterface.h
// Author: Changchang Wu (ccwu@cs.washington.edu)
// Description : data interface, the data format been uploaded to GPU
//
// Copyright (c) 2011 Changchang Wu (ccwu@cs.washington.edu)
// and the University of Washington at Seattle
//
// This library 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 3 of the License, or (at your option) any later version.
//
// This library 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.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef DATA_INTERFACE_GPU_H
#define DATA_INTERFACE_GPU_H
namespace PBA {
// ----------------------------WARNING------------------------------
// -----------------------------------------------------------------
// ROTATION CONVERSION:
// The internal rotation representation is 3x3 float matrix. Reading
// back the rotations as quaternion or Rodrigues's representation will
// cause inaccuracy, IF you have wrongly reconstructed cameras with
// a very very large focal length (typically also very far away).
// In this case, any small change in the rotation matrix, will cause
// a large reprojection error.
//
// ---------------------------------------------------------------------
// RADIAL distortion is NOT enabled by default, use parameter "-md", -pd"
// or set ConfigBA::__use_radial_distortion to 1 or -1 to enable it.
// ---------------------------------------------------------------------------
//transfer data type with 4-float alignment
#define CameraT CameraT_
#define Point3D Point3D_
template<class FT>
struct CameraT_
{
typedef FT float_t;
//////////////////////////////////////////////////////
float_t f; // single focal length, K = [f, 0, 0; 0 f 0; 0 0 1]
float_t t[3]; // T in P = K[R T], T = - RC
float_t m[3][3]; // R in P = K[R T].
float_t radial; // WARNING: BE careful with the radial distortion model.
float_t distortion_type;
float_t constant_camera;
//////////////////////////////////////////////////////////
CameraT_() { radial = 0; distortion_type = 0; constant_camera = 0; }
//////////////////////////////////////////////
template <class CameraX> void SetCameraT(const CameraX & cam)
{
f = (float_t)cam.f;
t[0] = (float_t)cam.t[0]; t[1] = (float_t)cam.t[1]; t[2] = (float_t)cam.t[2];
for(int i = 0; i < 3; ++i) for(int j = 0; j < 3; ++j) m[i][j] = (float_t)cam.m[i][j];
radial = (float_t)cam.radial;
distortion_type = (float_t)cam.distortion_type;
constant_camera = (float_t)cam.constant_camera;
}
//////////////////////////////////////////
enum {
CAMERA_VARIABLE = 0,
CAMERA_FIXEDINTRINSIC = (1<<0),
CAMERA_FIXEDEXTRINSIC = (1<<1),
};
void SetVariableCamera() {(int&)constant_camera = CAMERA_VARIABLE;}
void SetFixedIntrinsic() {(int&)constant_camera = CAMERA_FIXEDINTRINSIC;}
void SetFixedExtrinsic() {(int&)constant_camera = CAMERA_FIXEDEXTRINSIC;}
void SetConstantCamera() {(int&)constant_camera = CAMERA_FIXEDINTRINSIC|CAMERA_FIXEDEXTRINSIC;}
//////////////////////////////////////
template <class Float> void SetFocalLength(Float F){ f = (float_t) F; }
float_t GetFocalLength() const{return f;}
template <class Float> void SetMeasurementDistortion(Float r) {radial = (float_t) r; distortion_type = -1;}
float_t GetMeasurementDistortion() const {return distortion_type == -1 ? radial : 0; }
//normalize radial distortion that applies to angle will be (radial * f * f);
template <class Float> void SetNormalizedMeasurementDistortion(Float r) {SetMeasurementDistortion(r / (f * f)); }
float_t GetNormalizedMeasurementDistortion() const{return GetMeasurementDistortion() * (f * f); }
//use projection distortion
template <class Float> void SetProjectionDistortion(Float r) {radial = float_t(r); distortion_type = 1; }
template <class Float> void SetProjectionDistortion(const Float* r) {SetProjectionDistortion(r[0]); }
float_t GetProjectionDistortion() {return distortion_type == 1 ? radial : 0; }
template <class Float> void SetRodriguesRotation(const Float r[3])
{
double a = sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]);
double ct = a==0.0?0.5:(1.0-cos(a))/a/a;
double st = a==0.0?1:sin(a)/a;
m[0][0]=float_t(1.0 - (r[1]*r[1] + r[2]*r[2])*ct);
m[0][1]=float_t(r[0]*r[1]*ct - r[2]*st);
m[0][2]=float_t(r[2]*r[0]*ct + r[1]*st);
m[1][0]=float_t(r[0]*r[1]*ct + r[2]*st);
m[1][1]=float_t(1.0 - (r[2]*r[2] + r[0]*r[0])*ct);
m[1][2]=float_t(r[1]*r[2]*ct - r[0]*st);
m[2][0]=float_t(r[2]*r[0]*ct - r[1]*st);
m[2][1]=float_t(r[1]*r[2]*ct + r[0]*st);
m[2][2]=float_t(1.0 - (r[0]*r[0] + r[1]*r[1])*ct );
}
template <class Float> void GetRodriguesRotation(Float r[3]) const
{
double a = (m[0][0]+m[1][1]+m[2][2]-1.0)/2.0;
const double epsilon = 0.01;
if( fabs(m[0][1] - m[1][0]) < epsilon &&
fabs(m[1][2] - m[2][1]) < epsilon &&
fabs(m[0][2] - m[2][0]) < epsilon )
{
if( fabs(m[0][1] + m[1][0]) < 0.1 &&
fabs(m[1][2] + m[2][1]) < 0.1 &&
fabs(m[0][2] + m[2][0]) < 0.1 && a > 0.9)
{
r[0] = 0;
r[1] = 0;
r[2] = 0;
}
else
{
const Float ha = Float(sqrt(0.5) * 3.14159265358979323846);
double xx = (m[0][0]+1.0)/2.0;
double yy = (m[1][1]+1.0)/2.0;
double zz = (m[2][2]+1.0)/2.0;
double xy = (m[0][1]+m[1][0])/4.0;
double xz = (m[0][2]+m[2][0])/4.0;
double yz = (m[1][2]+m[2][1])/4.0;
if ((xx > yy) && (xx > zz))
{
if (xx< epsilon)
{
r[0] = 0; r[1] = r[2] = ha;
} else
{
double t = sqrt(xx) ;
r[0] = Float(t * 3.14159265358979323846);
r[1] = Float(xy/t * 3.14159265358979323846);
r[2] = Float(xz/t * 3.14159265358979323846);
}
} else if (yy > zz)
{
if (yy< epsilon)
{
r[0] = r[2] = ha; r[1] = 0;
} else
{
double t = sqrt(yy);
r[0] = Float(xy/t* 3.14159265358979323846);
r[1] = Float( t * 3.14159265358979323846);
r[2] = Float(yz/t* 3.14159265358979323846);
}
} else
{
if (zz< epsilon)
{
r[0] = r[1] = ha; r[2] = 0;
} else
{
double t = sqrt(zz);
r[0] = Float(xz/ t* 3.14159265358979323846);
r[1] = Float(yz/ t* 3.14159265358979323846);
r[2] = Float( t * 3.14159265358979323846);
}
}
}
}
else
{
a = acos(a);
double b = 0.5*a/sin(a);
r[0] = Float(b*(m[2][1]-m[1][2]));
r[1] = Float(b*(m[0][2]-m[2][0]));
r[2] = Float(b*(m[1][0]-m[0][1]));
}
}
////////////////////////
template <class Float> void SetQuaternionRotation(const Float q[4])
{
double qq = sqrt(q[0]*q[0]+q[1]*q[1]+q[2]*q[2]+q[3]*q[3]);
double qw, qx, qy, qz;
if(qq>0)
{
qw=q[0]/qq;
qx=q[1]/qq;
qy=q[2]/qq;
qz=q[3]/qq;
}else
{
qw = 1;
qx = qy = qz = 0;
}
m[0][0]=float_t(qw*qw + qx*qx- qz*qz- qy*qy );
m[0][1]=float_t(2*qx*qy -2*qz*qw );
m[0][2]=float_t(2*qy*qw + 2*qz*qx);
m[1][0]=float_t(2*qx*qy+ 2*qw*qz);
m[1][1]=float_t(qy*qy+ qw*qw - qz*qz- qx*qx);
m[1][2]=float_t(2*qz*qy- 2*qx*qw);
m[2][0]=float_t(2*qx*qz- 2*qy*qw);
m[2][1]=float_t(2*qy*qz + 2*qw*qx );
m[2][2]=float_t(qz*qz+ qw*qw- qy*qy- qx*qx);
}
template <class Float> void GetQuaternionRotation(Float q[4]) const
{
q[0]= 1 + m[0][0] + m[1][1] + m[2][2];
if(q[0]>0.000000001)
{
q[0] = sqrt(q[0])/2.0;
q[1]= (m[2][1] - m[1][2])/( 4.0 *q[0]);
q[2]= (m[0][2] - m[2][0])/( 4.0 *q[0]);
q[3]= (m[1][0] - m[0][1])/( 4.0 *q[0]);
}else
{
double s;
if ( m[0][0] > m[1][1] && m[0][0] > m[2][2] )
{
s = 2.0 * sqrt( 1.0 + m[0][0] - m[1][1] - m[2][2]);
q[1] = 0.25 * s;
q[2] = (m[0][1] + m[1][0] ) / s;
q[3] = (m[0][2] + m[2][0] ) / s;
q[0] = (m[1][2] - m[2][1] ) / s;
} else if (m[1][1] > m[2][2])
{
s = 2.0 * sqrt( 1.0 + m[1][1] - m[0][0] - m[2][2]);
q[1] = (m[0][1] + m[1][0] ) / s;
q[2] = 0.25 * s;
q[3] = (m[1][2] + m[2][1] ) / s;
q[0] = (m[0][2] - m[2][0] ) / s;
} else
{
s = 2.0 * sqrt( 1.0 + m[2][2] - m[0][0] - m[1][1]);
q[1] = (m[0][2] + m[2][0] ) / s;
q[2] = (m[1][2] + m[2][1] ) / s;
q[3] = 0.25f * s;
q[0] = (m[0][1] - m[1][0] ) / s;
}
}
}
////////////////////////////////////////////////
template <class Float> void SetMatrixRotation(const Float * r)
{
for(int i = 0; i < 9; ++i) m[0][i] = float_t(r[i]);
}
template <class Float> void GetMatrixRotation(Float * r) const
{
for(int i = 0; i < 9; ++i) r[i] = Float(m[0][i]);
}
float GetRotationMatrixDeterminant()const
{
return m[0][0]*m[1][1]*m[2][2] +
m[0][1]*m[1][2]*m[2][0] +
m[0][2]*m[1][0]*m[2][1] -
m[0][2]*m[1][1]*m[2][0] -
m[0][1]*m[1][0]*m[2][2] -
m[0][0]*m[1][2]*m[2][1];
}
///////////////////////////////////////
template <class Float> void SetTranslation(const Float T[3])
{
t[0] = (float_t)T[0];
t[1] = (float_t)T[1];
t[2] = (float_t)T[2];
}
template <class Float> void GetTranslation(Float T[3]) const
{
T[0] = (Float)t[0];
T[1] = (Float)t[1];
T[2] = (Float)t[2];
}
/////////////////////////////////////////////
template <class Float> void SetCameraCenterAfterRotation(const Float c[3])
{
//t = - R * C
for(int j = 0; j < 3; ++j) t[j] = -float_t(double(m[j][0])*double(c[0]) + double(m[j][1])*double(c[1]) + double(m[j][2])*double(c[2]));
}
template <class Float> void GetCameraCenter(Float c[3]) const
{
//C = - R' * t
for(int j = 0; j < 3; ++j) c[j] = -Float(double(m[0][j])*double(t[0]) + double(m[1][j])*double(t[1]) + double(m[2][j])*double(t[2]));
}
////////////////////////////////////////////
template <class Float> void SetInvertedRT(const Float e[3], const Float T[3])
{
SetRodriguesRotation(e);
for(int i = 3; i < 9; ++i) m[0][i] = - m[0][i];
SetTranslation(T); t[1] = - t[1]; t[2] = -t[2];
}
template <class Float> void GetInvertedRT (Float e[3], Float T[3]) const
{
CameraT ci; ci.SetMatrixRotation(m[0]);
for(int i = 3; i < 9; ++i) ci.m[0][i] = - ci.m[0][i];
//for(int i = 1; i < 3; ++i) for(int j = 0; j < 3; ++j) ci.m[i][j] = - ci.m[i][j];
ci.GetRodriguesRotation(e);
GetTranslation(T); T[1] = - T[1]; T[2] = -T[2];
}
template <class Float> void SetInvertedR9T(const Float e[9], const Float T[3])
{
//for(int i = 0; i < 9; ++i) m[0][i] = (i < 3 ? e[i] : - e[i]);
//SetTranslation(T); t[1] = - t[1]; t[2] = -t[2];
m[0][0] = e[0]; m[0][1] = e[1]; m[0][2] = e[2];
m[1][0] = -e[3]; m[1][1] = -e[4]; m[1][2] = -e[5];
m[2][0] = -e[6]; m[2][1] = -e[7]; m[2][2] = -e[8];
t[0] = T[0]; t[1] = -T[1]; t[2] = -T[2];
}
template<class Float> void GetInvertedR9T(Float e[9], Float T[3]) const
{
e[0] = m[0][0]; e[1] = m[0][1]; e[2] = m[0][2];
e[3] = - m[1][0]; e[4] = -m[1][1]; e[5] = -m[1][2];
e[6] = -m[2][0]; e[7] = -m[2][1]; e[8] = -m[2][2] ;
T[0] = t[0]; T[1] = -t[1]; T[2] = -t[2];
}
};
template<class FT>
struct Point3D
{
typedef FT float_t;
float_t xyz[3]; //3D point location
float_t reserved; //alignment
////////////////////////////////
template <class Float> void SetPoint(Float x, Float y, Float z)
{
xyz[0] = (float_t) x;
xyz[1] = (float_t) y;
xyz[2] = (float_t) z;
reserved = 0;
}
template <class Float> void SetPoint(const Float * p)
{
xyz[0] = (float_t) p[0];
xyz[1] = (float_t) p[1];
xyz[2] = (float_t) p[2];
reserved = 0;
}
template <class Float> void GetPoint(Float* p) const
{
p[0] = (Float) xyz[0];
p[1] = (Float) xyz[1];
p[2] = (Float) xyz[2];
}
template <class Float> void GetPoint(Float&x, Float&y, Float&z) const
{
x = (Float) xyz[0];
y = (Float) xyz[1];
z = (Float) xyz[2];
}
};
#undef CameraT
#undef Point3D
typedef CameraT_<float> CameraT;
typedef CameraT_<double> CameraD;
typedef Point3D_<float> Point3D;
typedef Point3D_<double> Point3B;
struct Point2D
{
float x, y;
////////////////////////////////////////////////////////
Point2D(){}
template <class Float> Point2D(Float X, Float Y) {SetPoint2D(X, Y); }
template <class Float> void SetPoint2D(Float X, Float Y) { x = (float) X; y = (float) Y; }
template <class Float> void GetPoint2D(Float&X, Float&Y) const { X = (Float) x; Y = (Float) y; }
};
} // namespace PBA
#endif