⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atancamera.cc

📁 this is software for visual SLAM
💻 CC
字号:
// Copyright 2008 Isis Innovation Limited#include "ATANCamera.h"#include <TooN/helpers.h>#include <cvd/vector_image_ref.h>#include <iostream>#include <gvars3/instances.h>using namespace std;using namespace CVD;using namespace GVars3;ATANCamera::ATANCamera(string sName){  // The camera name is used to find the camera's parameters in a GVar.  msName = sName;  GV2.Register(mgvvCameraParams, sName+".Parameters", mvDefaultParams, HIDDEN | FATAL_IF_NOT_DEFINED);  mvImageSize[0] = 640.0;  mvImageSize[1] = 480.0;  RefreshParams();}void ATANCamera::SetImageSize(Vector<2> vImageSize){  mvImageSize = vImageSize;  RefreshParams();};void ATANCamera::RefreshParams() {  // This updates internal member variables according to the current camera parameters,  // and the currently selected target image size.  //    // First: Focal length and image center in pixel coordinates  mvFocal[0] = mvImageSize[0] * (*mgvvCameraParams)[0];  mvFocal[1] = mvImageSize[1] * (*mgvvCameraParams)[1];  mvCenter[0] = mvImageSize[0] * (*mgvvCameraParams)[2] - 0.5;  mvCenter[1] = mvImageSize[1] * (*mgvvCameraParams)[3] - 0.5;    // One over focal length  mvInvFocal[0] = 1.0 / mvFocal[0];  mvInvFocal[1] = 1.0 / mvFocal[1];  // Some radial distortion parameters..  mdW =  (*mgvvCameraParams)[4];  md2Tan = 2.0 * tan(mdW / 2.0);  mdOneOver2Tan = 1.0 / md2Tan;  mdWinv = 1.0 / mdW;    // work out biggest radius in image  Vector<2> v2;  v2[0]= max((*mgvvCameraParams)[2], 1.0 - (*mgvvCameraParams)[2]) / (*mgvvCameraParams)[0];  v2[1]= max((*mgvvCameraParams)[3], 1.0 - (*mgvvCameraParams)[3]) / (*mgvvCameraParams)[1];  mdLargestRadius = invrtrans(sqrt(v2*v2));    // At what stage does the model become invalid?  mdMaxR = 1.5 * mdLargestRadius; // (pretty arbitrary)  // work out world radius of one pixel  // (This only really makes sense for square-ish pixels)  {    Vector<2> v2Center = UnProject(mvImageSize / 2);    Vector<2> v2RootTwoAway = UnProject(mvImageSize / 2 + vec(ImageRef(1,1)));    Vector<2> v2Diff = v2Center - v2RootTwoAway;    mdOnePixelDist = sqrt(v2Diff * v2Diff) / sqrt(2.0);  }    // Work out the linear projection values for the UFB  {    // First: Find out how big the linear bounding rectangle must be    vector<Vector<2> > vv2Verts;    vv2Verts.push_back(UnProject((make_Vector, -0.5, -0.5)));    vv2Verts.push_back(UnProject((make_Vector, mvImageSize[0]-0.5, -0.5)));    vv2Verts.push_back(UnProject((make_Vector, mvImageSize[0]-0.5, mvImageSize[1]-0.5)));    vv2Verts.push_back(UnProject((make_Vector, -0.5, mvImageSize[1]-0.5)));    Vector<2> v2Min = vv2Verts[0];    Vector<2> v2Max = vv2Verts[0];    for(int i=0; i<4; i++)      for(int j=0; j<2; j++)	{	  if(vv2Verts[i][j] < v2Min[j]) v2Min[j] = vv2Verts[i][j];	  if(vv2Verts[i][j] > v2Max[j]) v2Max[j] = vv2Verts[i][j];	}    mvImplaneTL = v2Min;    mvImplaneBR = v2Max;        // Store projection parameters to fill this bounding box    Vector<2> v2Range = v2Max - v2Min;    mvUFBLinearInvFocal = v2Range;    mvUFBLinearFocal[0] = 1.0 / mvUFBLinearInvFocal[0];    mvUFBLinearFocal[1] = 1.0 / mvUFBLinearInvFocal[1];    mvUFBLinearCenter[0] = -1.0 * v2Min[0] * mvUFBLinearFocal[0];    mvUFBLinearCenter[1] = -1.0 * v2Min[1] * mvUFBLinearFocal[1];  }  }// Project from the camera z=1 plane to image pixels,// while storing intermediate calculation results in member variablesVector<2> ATANCamera::Project(const Vector<2>& vCam){  mvLastCam = vCam;  mdLastR = sqrt(vCam * vCam);  mbInvalid = (mdLastR > mdMaxR);  mdLastFactor = rtrans_factor(mdLastR);  mdLastDistR = mdLastFactor * mdLastR;  mvLastDistCam = mdLastFactor * mvLastCam;    mvLastIm[0] = mvCenter[0] + mvFocal[0] * mvLastDistCam[0];  mvLastIm[1] = mvCenter[1] + mvFocal[1] * mvLastDistCam[1];    return mvLastIm;}// Un-project from image pixel coords to the camera z=1 plane// while storing intermediate calculation results in member variablesVector<2> ATANCamera::UnProject(const Vector<2>& v2Im){  mvLastIm = v2Im;  mvLastDistCam[0] = (mvLastIm[0] - mvCenter[0]) * mvInvFocal[0];  mvLastDistCam[1] = (mvLastIm[1] - mvCenter[1]) * mvInvFocal[1];  mdLastDistR = sqrt(mvLastDistCam * mvLastDistCam);  mdLastR = invrtrans(mdLastDistR);  double dFactor;  if(mdLastDistR > 0.01)    dFactor =  mdLastR / mdLastDistR;  else    dFactor = 1.0;  mdLastFactor = 1.0 / dFactor;  mvLastCam = dFactor * mvLastDistCam;  return mvLastCam;}// Utility function for easy drawing with OpenGL// C.f. comment in top of ATANCamera.hMatrix<4> ATANCamera::MakeUFBLinearFrustumMatrix(double near, double far){  Matrix<4> m4;  Zero(m4);  double left = mvImplaneTL[0] * near;  double right = mvImplaneBR[0] * near;  double top = mvImplaneTL[1] * near;  double bottom = mvImplaneBR[1] * near;    // The openGhelL frustum manpage is A PACK OF LIES!!  // Two of the elements are NOT what the manpage says they should be.  // Anyway, below code makes a frustum projection matrix  // Which projects a RHS-coord frame with +z in front of the camera  // Which is what I usually want, instead of glFrustum's LHS, -z idea.  m4[0][0] = (2 * near) / (right - left);  m4[1][1] = (2 * near) / (top - bottom);    m4[0][2] = (right + left) / (left - right);  m4[1][2] = (top + bottom) / (bottom - top);  m4[2][2] = (far + near) / (far - near);  m4[3][2] = 1;    m4[2][3] = 2*near*far / (near - far);  return m4;};Matrix<2,2> ATANCamera::GetProjectionDerivs(){  // get the derivative of image frame wrt camera z=1 frame at the last computed projection  // in the form (d im1/d cam1, d im1/d cam2)  //             (d im2/d cam1, d im2/d cam2)    double dFracBydx;  double dFracBydy;    double &k = md2Tan;  double &x = mvLastCam[0];  double &y = mvLastCam[1];  double &r = mdLastR;    if(r < 0.01)    {      dFracBydx = 0.0;      dFracBydy = 0.0;    }  else    {      dFracBydx = 	mdWinv * (k * x) / (r*r*(1 + k*k*r*r)) - x * mdLastFactor / (r*r);       dFracBydy = 	mdWinv * (k * y) / (r*r*(1 + k*k*r*r)) - y * mdLastFactor / (r*r);     }    Matrix<2> m2Derivs;    m2Derivs[0][0] = mvFocal[0] * (dFracBydx * x + mdLastFactor);    m2Derivs[1][0] = mvFocal[1] * (dFracBydx * y);    m2Derivs[0][1] = mvFocal[0] * (dFracBydy * x);    m2Derivs[1][1] = mvFocal[1] * (dFracBydy * y + mdLastFactor);      return m2Derivs;}Matrix<2,NUMTRACKERCAMPARAMETERS> ATANCamera::GetCameraParameterDerivs(){  // Differentials wrt to the camera parameters  // Use these to calibrate the camera  // No need for this to be quick, so do them numerically    Matrix<2, NUMTRACKERCAMPARAMETERS> m2NNumDerivs;  Vector<NUMTRACKERCAMPARAMETERS> vNNormal = *mgvvCameraParams;  Vector<2> v2Cam = mvLastCam;  Vector<2> v2Out = Project(v2Cam);  for(int i=0; i<NUMTRACKERCAMPARAMETERS; i++)    {      Vector<NUMTRACKERCAMPARAMETERS> vNUpdate;      Zero(vNUpdate);      vNUpdate[i] += 0.001;      UpdateParams(vNUpdate);       Vector<2> v2Out_B = Project(v2Cam);      m2NNumDerivs.T()[i] = (v2Out_B - v2Out) / 0.001;      *mgvvCameraParams = vNNormal;      RefreshParams();    }  return m2NNumDerivs;}void ATANCamera::UpdateParams(Vector<5> vUpdate){  // Update the camera parameters; use this as part of camera calibration.  (*mgvvCameraParams) = (*mgvvCameraParams) + vUpdate;  RefreshParams();}Vector<2> ATANCamera::UFBProject(const Vector<2>& vCam){  // Project from camera z=1 plane to UFB, storing intermediate calc results.  mvLastCam = vCam;  mdLastR = sqrt(vCam * vCam);  mbInvalid = (mdLastR > mdMaxR);  mdLastFactor = rtrans_factor(mdLastR);  mdLastDistR = mdLastFactor * mdLastR;  mvLastDistCam = mdLastFactor * mvLastCam;    mvLastIm[0] = (*mgvvCameraParams)[2]  + (*mgvvCameraParams)[0] * mvLastDistCam[0];  mvLastIm[1] = (*mgvvCameraParams)[3]  + (*mgvvCameraParams)[1] * mvLastDistCam[1];  return mvLastIm;}Vector<2> ATANCamera::UFBUnProject(const Vector<2>& v2Im){  mvLastIm = v2Im;  mvLastDistCam[0] = (mvLastIm[0] - (*mgvvCameraParams)[2]) / (*mgvvCameraParams)[0];  mvLastDistCam[1] = (mvLastIm[1] - (*mgvvCameraParams)[3]) / (*mgvvCameraParams)[1];  mdLastDistR = sqrt(mvLastDistCam * mvLastDistCam);  mdLastR = invrtrans(mdLastDistR);  double dFactor;  if(mdLastDistR > 0.01)    dFactor =  mdLastR / mdLastDistR;  else    dFactor = 1.0;  mdLastFactor = 1.0 / dFactor;  mvLastCam = dFactor * mvLastDistCam;  return mvLastCam;}const Vector<NUMTRACKERCAMPARAMETERS> ATANCamera::mvDefaultParams = (make_Vector, 0.5, 0.75, 0.5, 0.5, 0.1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -