示例#1
0
void Reconstruction::updateMesh( LaplacianMesh& resMesh )
{
    const mat&	paramMat = this->refMesh.GetParamMatrix();
    
    mat matC = TraceManager::imageDatabase->getRefCamera().ReprojectPoints(reshape(c, refMesh.GetNCtrlPoints(), 2));
//    mat matC = reshape(c, refMesh.GetNCtrlPoints(), 3);

    // Update vertex coordinates
    resMesh.SetVertexCoords(paramMat * matC);

    // Resulting mesh yields a correct projection on image but it does not preserve lengths.
    // So we need to compute the scale factor and multiply with matC

    // Determine on which side the mesh lies: -Z or Z
    double meanZ = mean(resMesh.GetVertexCoords().col(2));
    int globalSign = meanZ > 0 ? 1 : -1;

    const vec& resMeshEdgeLens = resMesh.ComputeEdgeLengths();
    const vec& refMeshEdgeLens = refMesh.GetEdgeLengths();

    // this seems no difference if do not scale the points?
    double scale = globalSign * norm(refMeshEdgeLens, 2) / norm(resMeshEdgeLens, 2);

    // Update vertex coordinates
    resMesh.SetVertexCoords(scale * paramMat * matC);
}
示例#2
0
void Reconstruction::ReconstructSoftConstr2D(const arma::vec& cInit, LaplacianMesh &resMesh) {
    const mat& paramMat = refMesh.GetParamMatrix();
    const mat& bigP		= refMesh.GetBigParamMat();
    
    if (cOptimal.is_empty()) {
        cOptimal = reshape(refMesh.GetVertexCoords().rows(refMesh.GetCtrlPointIDs()), refMesh.GetNCtrlPoints()*3, 1 );
    }
    
    SoftConstrFunction2D function( bigP, this->GetBPwAP(), refMesh.GetEdges(), refMesh.GetEdgeLengths());
    
    if ( this->usePrevFrameToInit && !isFirstFrame )
        cOptimal = softConstrOptimize.OptimizeLagrange(cOptimal, function, resMesh);
    else
        cOptimal = softConstrOptimize.OptimizeLagrange(cInit, function, resMesh);
    
    arma::mat cOptimalMat = arma::mat(reshape(cOptimal, refMesh.GetNCtrlPoints(), 3));
    if ( mean(cOptimalMat.col(2)) < 0 ) {		// Change the sign if the reconstruction is behind the camera. This happens because we take cOptimal as initial value for constrained optimization.
        cOptimalMat = -cOptimalMat;
    }
    
    // Update vertex coordinates
    resMesh.SetVertexCoords(paramMat*(cOptimalMat));
    
    isFirstFrame = false;
}
示例#3
0
void Reconstruction::reconstructPlanarUnconstr( const uvec& matchIdxs, double wr, LaplacianMesh& resMesh )
{
    Timer timer;
    
    const mat&	paramMat = this->refMesh.GetParamMatrix();	// Parameterization matrix
    
    // Build the matrix MPwAP = [MP; wr*AP] and compute: (MPwAP)' * (MPwAP)
    this->computeCurrentMatrices( matchIdxs, wr);
    
    // --------------- Eigen value decomposition --------------------------
    mat V;
    vec s;
    timer.start();
    
    // 此处最小的特征值只是其中一个解,在下面会对这个解进行Scale使得它的边长和ref mesh的边长相等
    eig_sym(s, V, this->MPwAPtMPwAP);
    timer.stop();
//    cout << "Eigen(): " << timer.getElapsedTimeInMilliSec() << " ms"<< endl;
    const vec& c = V.col(0);
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    mat matC = reshape(c, refMesh.GetNCtrlPoints(), 3);
    
    // Update vertex coordinates
    resMesh.SetVertexCoords(paramMat * matC);
    
    // Resulting mesh yields a correct projection on image but it does not preserve lengths.
    // So we need to compute the scale factor and multiply with matC
    
    // Determine on which side the mesh lies: -Z or Z
    double meanZ = mean(resMesh.GetVertexCoords().col(2));
    int globalSign = meanZ > 0 ? 1 : -1;
    
    const vec& resMeshEdgeLens = resMesh.ComputeEdgeLengths();
    const vec& refMeshEdgeLens = refMesh.GetEdgeLengths();
    
    double scale = globalSign * norm(refMeshEdgeLens, 2) / norm(resMeshEdgeLens, 2);
    
    // Update vertex coordinates
    resMesh.SetVertexCoords(scale * paramMat * matC);
}
void Reconstruction::ReconstructIneqConstr(const vec& cInit, LaplacianMesh& resMesh)
{
  const mat& paramMat = refMesh.GetParamMatrix();
  const mat& bigP     = refMesh.GetBigParamMat();

  static bool isFirstFrame = true;
  static vec cOptimal = reshape(refMesh.GetVertexCoords().rows(refMesh.GetCtrlPointIDs()), refMesh.GetNCtrlPoints()*3, 1);

  // Objective function: use MPwAP which was already computed in unconstrained reconstruction
  ObjectiveFunction *objtFunction;

  if (this->useTemporal && !isFirstFrame) 
    objtFunction = new ObjectiveFunction(this->GetMPwAP(), this->timeSmoothAlpha, cOptimal);
  else
    objtFunction = new ObjectiveFunction(this->GetMPwAP());

  // Constrained function
  IneqConstrFunction cstrFunction(bigP, refMesh.GetEdges(), refMesh.GetEdgeLengths());

  if (this->usePrevFrameToInit && !isFirstFrame)
    cOptimal = ineqConstrOptimize.OptimizeLagrange(cOptimal, *objtFunction, cstrFunction);
  else
    cOptimal = ineqConstrOptimize.OptimizeLagrange(cInit, *objtFunction, cstrFunction);

  mat cOptimalMat = reshape(cOptimal, refMesh.GetNCtrlPoints(), 3);
  if (cOptimalMat(0,2) < 0)
  {
    // Change the sign if the reconstruction is behind the camera. 
    // This happens because we take cOptimal as initial value for constrained optimization.
    cOptimalMat = -cOptimalMat;
  }

  // Update vertex coordinates
  resMesh.SetVertexCoords(paramMat*cOptimalMat);

  isFirstFrame = false;
  delete objtFunction;
}