Ejemplo n.º 1
4
// @from http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/01/msg00173.html
static bool pinv(const Eigen::Matrix2d& a, Eigen::Matrix2d& a_pinv)
{
    // see : http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse#The_general_case_and_the_SVD_method

    if (a.rows() < a.cols())
        return false;

    // SVD
    Eigen::JacobiSVD<Eigen::Matrix2d> svdA(a, Eigen::ComputeFullU | Eigen::ComputeFullV);
    Eigen::Vector2d vSingular = svdA.singularValues();

    // Build a diagonal matrix with the Inverted Singular values
    // The pseudo inverted singular matrix is easy to compute :
    // is formed by replacing every nonzero entry by its reciprocal (inversing).
    Eigen::Vector2d vPseudoInvertedSingular(svdA.matrixV().cols(),1);

    for (int iRow = 0; iRow < vSingular.rows(); iRow++)
    {
        if (fabs(vSingular(iRow)) <= 1e-10) // Todo : Put epsilon in parameter
        {
            vPseudoInvertedSingular(iRow, 0) = 0.;
        }
        else
        {
            vPseudoInvertedSingular(iRow, 0) = 1. / vSingular(iRow);
        }
    }

    // A little optimization here
    Eigen::Matrix2d mAdjointU = svdA.matrixU().adjoint().block(0, 0, vSingular.rows(), svdA.matrixU().adjoint().cols());

    // Pseudo-Inversion : V * S * U'
    a_pinv = (svdA.matrixV() * vPseudoInvertedSingular.asDiagonal()) * mAdjointU;

    return true;
}
/** Compute fundamental matrix out of eight feature correspondences between the previous and current frame.
 * @param std::vector<Match> vector with feature matches
 * @param std::vector<int> vector with eight indices of the vector with matches
 * @return Eigen::Matrix3f fundamental matrix */
Eigen::Matrix3f MonoOdometer5::getF(std::vector<Match> matches, std::vector<int> indices)
{
    int N = indices.size();

	// see Trucco & Verri, Introductory Techniques for 3D Computer Vision, chapter 6
    Eigen::Matrix<float, Eigen::Dynamic, 9> A;
    A.resize(N, 9);

    for(int i=0; i<N; i++)
    {
        cv::Point2f pPrev = matches[indices[i]].pPrev_;
        cv::Point2f pCurr = matches[indices[i]].pCurr_;
        
        A(i, 0) = pCurr.x * pPrev.x;
        A(i, 1) = pCurr.x * pPrev.y;
        A(i, 2) = pCurr.x;
        A(i, 3) = pCurr.y * pPrev.x;
        A(i, 4) = pCurr.y * pPrev.y;
        A(i, 5) = pCurr.y;
        A(i, 6) = pPrev.x;
        A(i, 7) = pPrev.y;
        A(i, 8) = 1;
    }
    
    Eigen::JacobiSVD<Eigen::Matrix<float, Eigen::Dynamic, 9>> svdA(A, Eigen::ComputeFullU | Eigen::ComputeFullV);

    Eigen::Matrix3f F;
    F << svdA.matrixV()(0, 8), svdA.matrixV()(1, 8), svdA.matrixV()(2, 8), svdA.matrixV()(3, 8), svdA.matrixV()(4, 8), svdA.matrixV()(5, 8), svdA.matrixV()(6, 8), svdA.matrixV()(7, 8), svdA.matrixV()(8, 8);
    
	// re-enforce rank 2 constraint on fundamental matrix
    Eigen::JacobiSVD<Eigen::Matrix3f> svdF(F, Eigen::ComputeFullU | Eigen::ComputeFullV);
    Eigen::Matrix3f D(Eigen::Matrix3f::Zero());
    D(0, 0) = svdF.singularValues()(0);
    D(1, 1) = svdF.singularValues()(1);
    
    F = (svdF.matrixU()) * D * (svdF.matrixV()).transpose();
    
    return F;
}
Ejemplo n.º 3
0
bool mitk::PivotCalibration::ComputePivotPoint()
{
  double defaultThreshold = 1e-1;

  std::vector<mitk::NavigationData::Pointer> _CheckedTransforms;
  for (size_t i = 0; i < m_NavigationDatas.size(); ++i)
  {
    if (!m_NavigationDatas.at(i)->IsDataValid())
    {
      MITK_WARN << "Skipping invalid transform " << i << ".";
      continue;
    }
    _CheckedTransforms.push_back(m_NavigationDatas.at(i));
  }

  if (_CheckedTransforms.empty())
  {
    MITK_WARN << "Checked Transforms are empty";
    return false;
  }

  unsigned int rows = 3 * _CheckedTransforms.size();
  unsigned int columns = 6;

  vnl_matrix< double > A(rows, columns), minusI(3, 3, 0), R(3, 3);
  vnl_vector< double > b(rows), x(columns), t(3);

  minusI(0, 0) = -1;
  minusI(1, 1) = -1;
  minusI(2, 2) = -1;

  //do the computation and set the internal variables
  unsigned int currentRow = 0;


  for (size_t i = 0; i < _CheckedTransforms.size(); ++i)
  {
    t = _CheckedTransforms.at(i)->GetPosition().GetVnlVector();// t = the current position of the tracked sensor
    t *= -1;
    b.update(t, currentRow); //b = combines the position for each collected transform in one column vector 
    R = _CheckedTransforms.at(i)->GetOrientation().rotation_matrix_transpose().transpose(); // R = the current rotation of the tracked sensor, *rotation_matrix_transpose().transpose() is used to obtain original matrix
    A.update(R, currentRow, 0); //A = the matrix which stores the rotations for each collected transform and -I
    A.update(minusI, currentRow, 3);
    currentRow += 3;
  }
  vnl_svd<double> svdA(A); //The singular value decomposition of matrix A
  svdA.zero_out_absolute(defaultThreshold);

  //there is a solution only if rank(A)=6 (columns are linearly
  //independent)
  if (svdA.rank() < 6)
  {
    MITK_WARN << "svdA.rank() < 6";
    return false;
  }
  else
  {
    x = svdA.solve(b); //x = the resulting pivot point

    m_ResultRMSError = (A * x - b).rms();  //the root mean sqaure error of the computation 

    //sets the Pivot Point
    m_ResultPivotPoint[0] = x[0];
    m_ResultPivotPoint[1] = x[1];
    m_ResultPivotPoint[2] = x[2];


  }
  return true;

}
Ejemplo n.º 4
0
Foam::chemPointISAT<CompType, ThermoType>::chemPointISAT
(
    TDACChemistryModel<CompType, ThermoType>& chemistry,
    const scalarField& phi,
    const scalarField& Rphi,
    const scalarSquareMatrix& A,
    const scalarField& scaleFactor,
    const scalar& tolerance,
    const label& completeSpaceSize,
    const dictionary& coeffsDict,
    binaryNode<CompType, ThermoType>* node
)
:
    chemistry_(chemistry),
    phi_(phi),
    Rphi_(Rphi),
    A_(A),
    scaleFactor_(scaleFactor),
    node_(node),
    completeSpaceSize_(completeSpaceSize),
    nGrowth_(0),
    nActiveSpecies_(chemistry.mechRed()->NsSimp()),
    simplifiedToCompleteIndex_(nActiveSpecies_),
    timeTag_(chemistry_.timeSteps()),
    lastTimeUsed_(chemistry_.timeSteps()),
    toRemove_(false),
    maxNumNewDim_(coeffsDict.lookupOrDefault("maxNumNewDim",0)),
    printProportion_(coeffsDict.lookupOrDefault("printProportion",false)),
    numRetrieve_(0),
    nLifeTime_(0),
    completeToSimplifiedIndex_
    (
        completeSpaceSize - (2 + (variableTimeStep() == 1 ? 1 : 0))
    )
{
    tolerance_ = tolerance;

    if (variableTimeStep())
    {
        nAdditionalEqns_ = 3;
        iddeltaT_ = completeSpaceSize - 1;
        scaleFactor_[iddeltaT_] *= phi_[iddeltaT_] / tolerance_;
    }
    else
    {
        nAdditionalEqns_ = 2;
        iddeltaT_ = completeSpaceSize; // will not be used
    }
    idT_ = completeSpaceSize - nAdditionalEqns_;
    idp_ = completeSpaceSize - nAdditionalEqns_ + 1;

    bool isMechRedActive = chemistry_.mechRed()->active();
    if (isMechRedActive)
    {
        for (label i=0; i<completeSpaceSize-nAdditionalEqns_; i++)
        {
            completeToSimplifiedIndex_[i] =
                chemistry.completeToSimplifiedIndex()[i];
        }
        for (label i=0; i<nActiveSpecies_; i++)
        {
            simplifiedToCompleteIndex_[i] =
                chemistry.simplifiedToCompleteIndex()[i];
        }
    }

    label reduOrCompDim = completeSpaceSize;
    if (isMechRedActive)
    {
        reduOrCompDim = nActiveSpecies_+nAdditionalEqns_;
    }

    // SVD decomposition A = U*D*V^T
    SVD svdA(A);

    scalarDiagonalMatrix D(reduOrCompDim);
    const scalarDiagonalMatrix& S = svdA.S();

    // Replace the value of vector D by max(D, 1/2), first ISAT paper
    for (label i=0; i<reduOrCompDim; i++)
    {
        D[i] = max(S[i], 0.5);
    }

    // Rebuild A with max length, tol and scale factor before QR decomposition
    scalarRectangularMatrix Atilde(reduOrCompDim);

    // Result stored in Atilde
    multiply(Atilde, svdA.U(), D, svdA.V().T());

    for (label i=0; i<reduOrCompDim; i++)
    {
        for (label j=0; j<reduOrCompDim; j++)
        {
            label compi = i;

            if (isMechRedActive)
            {
                compi = simplifiedToCompleteIndex(i);
            }

            // SF*A/tolerance
            // (where SF is diagonal with inverse of scale factors)
            // SF*A is the same as dividing each line by the scale factor
            // corresponding to the species of this line
            Atilde(i, j) /= (tolerance*scaleFactor[compi]);
        }
    }

    // The object LT_ (the transpose of the Q) describe the EOA, since we have
    // A^T B^T B A that should be factorized into L Q^T Q L^T and is set in the
    // qrDecompose function
    LT_ = scalarSquareMatrix(Atilde);

    qrDecompose(reduOrCompDim, LT_);
}
/*
Description:

*/
bool PivotCalibration2::ComputePivotCalibration()
{
	if (this->ToolToReferenceMatrices.size() < 10)
	{
		this->ErrorText = "Not enough input transforms are available";
		return false;
	}

	if (this->GetMaximumToolOrientationDifferenceDeg() < this->MinimumOrientationDifferenceDeg)
	{
		this->ErrorText = "Not enough variation in the input transforms";
		return false;
	}

	unsigned int rows = 3 * this->ToolToReferenceMatrices.size();
	unsigned int columns = 6;


	vnl_matrix<double> A(rows, columns);

	vnl_matrix<double> minusI(3, 3, 0);
	minusI(0, 0) = -1;
	minusI(1, 1) = -1;
	minusI(2, 2) = -1;

	vnl_matrix<double> R(3, 3);
	vnl_vector<double> b(rows);
	vnl_vector<double> x(columns);
	vnl_vector<double> t(3);

	std::vector<vtkSmartPointer<vtkMatrix4x4> >::const_iterator it;
	std::vector<vtkSmartPointer<vtkMatrix4x4> >::const_iterator matricesEnd = this->ToolToReferenceMatrices.end();
	unsigned int currentRow;
	vtkMatrix4x4* referenceOrientationMatrix = this->ToolToReferenceMatrices.front();
	for (currentRow = 0, it = this->ToolToReferenceMatrices.begin(); it != matricesEnd; it++, currentRow += 3)
	{
		for (int i = 0; i < 3; i++)
		{
			t(i) = (*it)->GetElement(i, 3);
		}
		t *= -1;
		b.update(t, currentRow);

		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				R(i, j) = (*it)->GetElement(i, j);
			}
		}
		A.update(R, currentRow, 0);
		A.update(minusI, currentRow, 3);
	}

	vnl_svd<double> svdA(A);
	svdA.zero_out_absolute(1e-1);
	x = svdA.solve(b);

	//set the RMSE
	this->PivotRMSE = (A * x - b).rms();

	//set the transformation
	this->ToolTipToToolMatrix->SetElement(0, 3, x[0]);
	this->ToolTipToToolMatrix->SetElement(1, 3, x[1]);
	this->ToolTipToToolMatrix->SetElement(2, 3, x[2]);

	this->ErrorText.empty();
	return true;
}
Ejemplo n.º 6
0
void Lu::abskernel(MatrixXf P, MatrixXf Q, std::vector<Matrix3f > F, MatrixXf G){

   int n = P.cols();
   int i;
   
   //std::cout<<"P\n"<<P<<std::endl;
   //std::cout<<"Q\n"<<Q<<std::endl;
   //std::cout<<"-------------\n"<<std::endl;
   
   for( i=0; i<n;i++){
      Q.col(i)=F[i]*Q.col(i);
      
    //  std::cout<<"F\n"<<F[i]*Q.col(i)<<std::endl;
      
   }
   //std::cout<<"Q\n"<<Q<<std::endl;
   
   // compute P' and Q'
    Vector3f pbar;
    Vector3f qbar;
    Vector3f P_sum;
  
    Vector3f Q_sum;
    
    P_sum= Vector3f::Zero();
    Q_sum= Vector3f::Zero();
    
    for( i=0; i<n;i++){
      P_sum = P_sum+P.col(i);
      Q_sum = Q_sum+Q.col(i);
    }
    
    pbar=P_sum/n;
    qbar=Q_sum/n;
  // std::cout<<"pbar\n"<<pbar<<std::endl;
   // std::cout<<"qbar\n"<<qbar<<std::endl;

    for( i=0; i<n;i++){
      P.col(i)=P.col(i)-pbar;
      Q.col(i)=Q.col(i)-qbar;
    }
    
    //std::cout<<"P\n"<<P<<std::endl;
    //std::cout<<"Q\n"<<Q<<std::endl;
    /////////////use SVM method
    Matrix3f M=Matrix3f::Zero();
    Vector3f vq;
    Vector3f vp;
    Matrix3f Vs;
    
    for( i=0; i<n;i++){
       vq=Q.col(i);
       vp=P.col(i);
       
      Vs << vp[0]*vq[0],vp[0]*vq[1],vp[0]*vq[2],
            vp[1]*vq[0],vp[1]*vq[1],vp[1]*vq[2],
            vp[2]*vq[0],vp[2]*vq[1],vp[2]*vq[2];
      
       M = M+Vs;
    }
    
    //std::cout<<"M\n"<<M<<std::endl;
    //Matrix
    //M.svd().compute();
    JacobiSVD<Matrix3f> svdA(M,ComputeFullU | ComputeFullV);
    //svdA.compute();
    
    Matrix3f U=svdA.matrixU();
    Matrix3f V=svdA.matrixV();   
    
    Ri=V*U.transpose();
    
    //std::cout<<"U\n"<<U<<std::endl;
    //std::cout<<"V\n"<<V<<std::endl;
    //std::cout<<"Ri\n"<<Ri<<std::endl;
    
    if (sgn(Ri.determinant())==1.0){
     ti= estimate_t( Ri,G,F,P,n );
     //std::cout<<"ti\n"<<ti<<std::endl;
     
     if (ti(2)<0){
      //R=-[V(:,1:2) -V(:,3)]*U.';
      Matrix3f Va;
      Va<<V(0,0),V(0,1),-V(0,2),
          V(1,0),V(1,1),-V(1,2),
          V(2,0),V(2,1),-V(2,2);
           
       Ri=-Va*U.transpose();
       ti = estimate_t( Ri,G,F,P,n );
     }
     
    }else{
      
      Matrix3f Va;
      Va<<V(0,0),V(0,1),-V(0,2),
          V(1,0),V(1,1),-V(1,2),
          V(2,0),V(2,1),-V(2,2);
         // std::cout<<"Va\n"<<ti<<std::endl; 
     //R=[V(:,1:2) -V(:,3)]*U.';
      Ri=Va*U.transpose();
      
       ti = estimate_t( Ri,G,F,P,n );

    if (ti(2) < 0){ 
      //disp(['t_3 = ' num2str(t(3)) ]);
      // we need to invert the t 
      Ri =- V*U.transpose();
      ti = estimate_t( Ri,G,F,P,n );
  
    }
    
    }
   //  std::cout<<"ti\n"<<ti<<std::endl;
    
  Qout = xform(P, Ri, ti);
    // std::cout<<"Qout\n"<<Qout<<std::endl;

// calculate error
   err = 0;
   Vector3f vec;
   
for (i = 0 ;i< n; i++){
  vec = (Matrix3f::Identity()-F[i])*Qout.col(i);
  //std::cout<<"vec\n"<<vec<<std::endl;
  err = err + vec.dot(vec);
}

    //std::cout<<"err\n"<<err<<std::endl;
}