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); }
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; }
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; }