Go to the documentation of this file.00001
00002 #include "ATANCamera.h"
00003 #include <TooN/helpers.h>
00004 #include <cvd/vector_image_ref.h>
00005 #include <iostream>
00006 #include <gvars3/instances.h>
00007 using namespace std;
00008 using namespace CVD;
00009 using namespace GVars3;
00010
00011 ATANCamera::ATANCamera(TooN::Vector<5> params)
00012 {
00013
00014 msName = "Camera";
00015
00016 GV2.Register(mgvvCameraParams, "Camera.Parameters",params,HIDDEN | SILENT);
00017
00018 mvImageSize[0] = 640.0;
00019 mvImageSize[1] = 480.0;
00020 RefreshParams();
00021 }
00022
00023 void ATANCamera::SetImageSize(Vector<2> vImageSize)
00024 {
00025 mvImageSize = vImageSize;
00026 RefreshParams();
00027 };
00028
00029 void ATANCamera::RefreshParams()
00030 {
00031
00032
00033
00034
00035
00036 mvFocal[0] = mvImageSize[0] * (*mgvvCameraParams)[0];
00037 mvFocal[1] = mvImageSize[1] * (*mgvvCameraParams)[1];
00038 mvCenter[0] = mvImageSize[0] * (*mgvvCameraParams)[2] - 0.5;
00039 mvCenter[1] = mvImageSize[1] * (*mgvvCameraParams)[3] - 0.5;
00040
00041
00042 mvInvFocal[0] = 1.0 / mvFocal[0];
00043 mvInvFocal[1] = 1.0 / mvFocal[1];
00044
00045
00046 mdW = (*mgvvCameraParams)[4];
00047 if(mdW != 0.0)
00048 {
00049 md2Tan = 2.0 * tan(mdW / 2.0);
00050 mdOneOver2Tan = 1.0 / md2Tan;
00051 mdWinv = 1.0 / mdW;
00052 mdDistortionEnabled = 1.0;
00053 }
00054 else
00055 {
00056 mdWinv = 0.0;
00057 md2Tan = 0.0;
00058 mdDistortionEnabled = 0.0;
00059 }
00060
00061
00062 Vector<2> v2;
00063 v2[0]= max((*mgvvCameraParams)[2], 1.0 - (*mgvvCameraParams)[2]) / (*mgvvCameraParams)[0];
00064 v2[1]= max((*mgvvCameraParams)[3], 1.0 - (*mgvvCameraParams)[3]) / (*mgvvCameraParams)[1];
00065 mdLargestRadius = invrtrans(sqrt((double)(v2*v2)));
00066
00067
00068 mdMaxR = 1.5 * mdLargestRadius;
00069
00070
00071
00072 {
00073 Vector<2> v2Center = UnProject(mvImageSize / 2);
00074 Vector<2> v2RootTwoAway = UnProject(mvImageSize / 2 + vec(ImageRef(1,1)));
00075 Vector<2> v2Diff = v2Center - v2RootTwoAway;
00076 mdOnePixelDist = sqrt((double)(v2Diff * v2Diff)) / sqrt(2.0);
00077 }
00078
00079
00080 {
00081
00082 vector<Vector<2> > vv2Verts;
00083 vv2Verts.push_back(UnProject(makeVector( -0.5, -0.5)));
00084 vv2Verts.push_back(UnProject(makeVector( mvImageSize[0]-0.5, -0.5)));
00085 vv2Verts.push_back(UnProject(makeVector( mvImageSize[0]-0.5, mvImageSize[1]-0.5)));
00086 vv2Verts.push_back(UnProject(makeVector( -0.5, mvImageSize[1]-0.5)));
00087 Vector<2> v2Min = vv2Verts[0];
00088 Vector<2> v2Max = vv2Verts[0];
00089 for(int i=0; i<4; i++)
00090 for(int j=0; j<2; j++)
00091 {
00092 if(vv2Verts[i][j] < v2Min[j]) v2Min[j] = vv2Verts[i][j];
00093 if(vv2Verts[i][j] > v2Max[j]) v2Max[j] = vv2Verts[i][j];
00094 }
00095 mvImplaneTL = v2Min;
00096 mvImplaneBR = v2Max;
00097
00098
00099 Vector<2> v2Range = v2Max - v2Min;
00100 mvUFBLinearInvFocal = v2Range;
00101 mvUFBLinearFocal[0] = 1.0 / mvUFBLinearInvFocal[0];
00102 mvUFBLinearFocal[1] = 1.0 / mvUFBLinearInvFocal[1];
00103 mvUFBLinearCenter[0] = -1.0 * v2Min[0] * mvUFBLinearFocal[0];
00104 mvUFBLinearCenter[1] = -1.0 * v2Min[1] * mvUFBLinearFocal[1];
00105 }
00106
00107 }
00108
00109
00110
00111 Vector<2> ATANCamera::Project(const Vector<2>& vCam){
00112 mvLastCam = vCam;
00113 mdLastR = sqrt((double)(vCam * vCam));
00114 mbInvalid = (mdLastR > mdMaxR);
00115 mdLastFactor = rtrans_factor(mdLastR);
00116 mdLastDistR = mdLastFactor * mdLastR;
00117 mvLastDistCam = mdLastFactor * mvLastCam;
00118
00119 mvLastIm[0] = mvCenter[0] + mvFocal[0] * mvLastDistCam[0];
00120 mvLastIm[1] = mvCenter[1] + mvFocal[1] * mvLastDistCam[1];
00121
00122 return mvLastIm;
00123 }
00124
00125
00126
00127 Vector<2> ATANCamera::UnProject(const Vector<2>& v2Im)
00128 {
00129 mvLastIm = v2Im;
00130 mvLastDistCam[0] = (mvLastIm[0] - mvCenter[0]) * mvInvFocal[0];
00131 mvLastDistCam[1] = (mvLastIm[1] - mvCenter[1]) * mvInvFocal[1];
00132 mdLastDistR = sqrt((double)(mvLastDistCam * mvLastDistCam));
00133
00134 mdLastR = invrtrans(mdLastDistR);
00135 double dFactor;
00136 if(mdLastDistR > 0.01)
00137 dFactor = mdLastR / mdLastDistR;
00138 else
00139 dFactor = 1.0;
00140 mdLastFactor = 1.0 / dFactor;
00141 mvLastCam = dFactor * mvLastDistCam;
00142 return mvLastCam;
00143 }
00144
00145
00146
00147 Matrix<4> ATANCamera::MakeUFBLinearFrustumMatrix(double near, double far)
00148 {
00149 Matrix<4> m4 = Zeros;
00150
00151
00152 double left = mvImplaneTL[0] * near;
00153 double right = mvImplaneBR[0] * near;
00154 double top = mvImplaneTL[1] * near;
00155 double bottom = mvImplaneBR[1] * near;
00156
00157
00158
00159
00160
00161
00162 m4[0][0] = (2 * near) / (right - left);
00163 m4[1][1] = (2 * near) / (top - bottom);
00164
00165 m4[0][2] = (right + left) / (left - right);
00166 m4[1][2] = (top + bottom) / (bottom - top);
00167 m4[2][2] = (far + near) / (far - near);
00168 m4[3][2] = 1;
00169
00170 m4[2][3] = 2*near*far / (near - far);
00171
00172 return m4;
00173 };
00174
00175 Matrix<2,2> ATANCamera::GetProjectionDerivs()
00176 {
00177
00178
00179
00180
00181 double dFracBydx;
00182 double dFracBydy;
00183
00184 double &k = md2Tan;
00185 double &x = mvLastCam[0];
00186 double &y = mvLastCam[1];
00187 double r = mdLastR * mdDistortionEnabled;
00188
00189 if(r < 0.01)
00190 {
00191 dFracBydx = 0.0;
00192 dFracBydy = 0.0;
00193 }
00194 else
00195 {
00196 dFracBydx =
00197 mdWinv * (k * x) / (r*r*(1 + k*k*r*r)) - x * mdLastFactor / (r*r);
00198 dFracBydy =
00199 mdWinv * (k * y) / (r*r*(1 + k*k*r*r)) - y * mdLastFactor / (r*r);
00200 }
00201
00202 Matrix<2> m2Derivs;
00203
00204 m2Derivs[0][0] = mvFocal[0] * (dFracBydx * x + mdLastFactor);
00205 m2Derivs[1][0] = mvFocal[1] * (dFracBydx * y);
00206 m2Derivs[0][1] = mvFocal[0] * (dFracBydy * x);
00207 m2Derivs[1][1] = mvFocal[1] * (dFracBydy * y + mdLastFactor);
00208 return m2Derivs;
00209 }
00210
00211 Matrix<2,NUMTRACKERCAMPARAMETERS> ATANCamera::GetCameraParameterDerivs()
00212 {
00213
00214
00215
00216
00217 Matrix<2, NUMTRACKERCAMPARAMETERS> m2NNumDerivs;
00218 Vector<NUMTRACKERCAMPARAMETERS> vNNormal = *mgvvCameraParams;
00219 Vector<2> v2Cam = mvLastCam;
00220 Vector<2> v2Out = Project(v2Cam);
00221 for(int i=0; i<NUMTRACKERCAMPARAMETERS; i++)
00222 {
00223 if(i == NUMTRACKERCAMPARAMETERS-1 && mdW == 0.0)
00224 continue;
00225 Vector<NUMTRACKERCAMPARAMETERS> vNUpdate;
00226 vNUpdate = Zeros;
00227 vNUpdate[i] += 0.001;
00228 UpdateParams(vNUpdate);
00229 Vector<2> v2Out_B = Project(v2Cam);
00230 m2NNumDerivs.T()[i] = (v2Out_B - v2Out) / 0.001;
00231 *mgvvCameraParams = vNNormal;
00232 RefreshParams();
00233 }
00234 if(mdW == 0.0)
00235 m2NNumDerivs.T()[NUMTRACKERCAMPARAMETERS-1] = Zeros;
00236 return m2NNumDerivs;
00237 }
00238
00239 void ATANCamera::UpdateParams(Vector<5> vUpdate)
00240 {
00241
00242 (*mgvvCameraParams) = (*mgvvCameraParams) + vUpdate;
00243 RefreshParams();
00244 }
00245
00246 void ATANCamera::DisableRadialDistortion()
00247 {
00248
00249
00250 (*mgvvCameraParams)[NUMTRACKERCAMPARAMETERS-1] = 0.0;
00251 RefreshParams();
00252 }
00253
00254 Vector<2> ATANCamera::UFBProject(const Vector<2>& vCam)
00255 {
00256
00257 mvLastCam = vCam;
00258 mdLastR = sqrt((double)(vCam * vCam));
00259 mbInvalid = (mdLastR > mdMaxR);
00260 mdLastFactor = rtrans_factor(mdLastR);
00261 mdLastDistR = mdLastFactor * mdLastR;
00262 mvLastDistCam = mdLastFactor * mvLastCam;
00263
00264 mvLastIm[0] = (*mgvvCameraParams)[2] + (*mgvvCameraParams)[0] * mvLastDistCam[0];
00265 mvLastIm[1] = (*mgvvCameraParams)[3] + (*mgvvCameraParams)[1] * mvLastDistCam[1];
00266 return mvLastIm;
00267 }
00268
00269 Vector<2> ATANCamera::UFBUnProject(const Vector<2>& v2Im)
00270 {
00271 mvLastIm = v2Im;
00272 mvLastDistCam[0] = (mvLastIm[0] - (*mgvvCameraParams)[2]) / (*mgvvCameraParams)[0];
00273 mvLastDistCam[1] = (mvLastIm[1] - (*mgvvCameraParams)[3]) / (*mgvvCameraParams)[1];
00274 mdLastDistR = sqrt((double)(mvLastDistCam * mvLastDistCam));
00275 mdLastR = invrtrans(mdLastDistR);
00276 double dFactor;
00277 if(mdLastDistR > 0.01)
00278 dFactor = mdLastR / mdLastDistR;
00279 else
00280 dFactor = 1.0;
00281 mdLastFactor = 1.0 / dFactor;
00282 mvLastCam = dFactor * mvLastDistCam;
00283 return mvLastCam;
00284 }
00285
00286 const Vector<NUMTRACKERCAMPARAMETERS> ATANCamera::mvDefaultParams = makeVector(0.5, 0.75, 0.5, 0.5, 0.1);
00287