示例#1
0
void Reconstruction::ReconstructPlanarUnconstrOnce( const mat& matchesInit, LaplacianMesh& resMesh)
{
    // Input check
    if (matchesInit.n_rows == 0) {
        return;
    }
    
    Timer timer;
    
    double meanZ = mean(resMesh.GetVertexCoords().col(2));
    
    // scale wr due to distance : 0 - 200
    double	wr		= this->wrInit  * (meanZ / 200.);			// Currently used regularization weight
//    double	radius	= this->radiusInit;		// Currently used radius of the estimator
//    vec		reprojErrors;					// Reprojection errors
    
    // First, we need to build the correspondent matrix with all given matches to avoid re-computation
    this->buildCorrespondenceMatrix(matchesInit);
    
    // Then compute MPinit. Function reconstructPlanarUnconstr() will use part of MPinit w.r.t currently used matches
    this->MPinit = this->Minit * this->refMesh.GetBigParamMat();
    
    uvec matchesInitIdxs = linspace<uvec>(0, matchesInit.n_rows-1, matchesInit.n_rows);
    
    // Currently used matches represented by their indices. Initially, use all matches: [0,1,2..n-1]
    
    this->reconstructPlanarUnconstr(matchesInitIdxs, wr, resMesh);
}
示例#2
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);
}
示例#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);
}
示例#4
0
void Reconstruction::ReconstructPlanarUnconstrIter( const mat& matchesInit, LaplacianMesh& resMesh, uvec& inlierMatchIdxs )
{
    // Input check
    if (matchesInit.n_rows == 0) {
        inlierMatchIdxs.resize(0);
        return;
    }
    
    Timer timer;
    
    double	wr		= this->wrInit;			// Currently used regularization weight
    double	radius	= this->radiusInit;		// Currently used radius of the estimator
    vec		reprojErrors;					// Reprojection errors
    
    // First, we need to build the correspondent matrix with all given matches to avoid re-computation
    this->buildCorrespondenceMatrix(matchesInit);
    
    // Then compute MPinit. Function reconstructPlanarUnconstr() will use part of MPinit w.r.t currently used matches
    this->MPinit = this->Minit * this->refMesh.GetBigParamMat();
    
    uvec matchesInitIdxs = linspace<uvec>(0, matchesInit.n_rows-1, matchesInit.n_rows);
    
    // Currently used matches represented by their indices. Initially, use all matches: [0,1,2..n-1]
    inlierMatchIdxs = matchesInitIdxs;
    
    for (int i = 0; i < nUncstrIters; i++)
    {
        
        
        // If it is the final iteration, break and don't update "inlierMatchIdxs" or "weights", "radius"
        if (i == nUncstrIters - 1) {
            double meanZ = mean(resMesh.GetVertexCoords().col(2));
            
            this->reconstructPlanarUnconstr(inlierMatchIdxs, this->wrInit * (meanZ / 200.), resMesh);
            //cout << "Current radius: " << radius << endl;
            //cout << "Current wr: " << wr << endl;
            //Reconstruction::computeCurrentMatrices( currentMatchIdxs, 325 );	// For Fern
            break;
        } else {
            this->reconstructPlanarUnconstr(inlierMatchIdxs, wr, resMesh);
        }
        
        // Otherwise, remove outliers
        int iterTO = nUncstrIters - 2;
        if (i >= iterTO)
            reprojErrors = this->computeReprojectionErrors(resMesh, matchesInit, matchesInitIdxs);
        else
            reprojErrors = this->computeReprojectionErrors(resMesh, matchesInit, inlierMatchIdxs);
        
        uvec idxs = find( reprojErrors < radius );
        if ( idxs.n_elem == 0 )
            break;
        
        if (i >= iterTO)
            inlierMatchIdxs = matchesInitIdxs.elem( idxs );
        else
            inlierMatchIdxs = inlierMatchIdxs.elem( idxs );
        
        // Update parameters
        wr		= wr 	 / Reconstruction::ROBUST_SCALE;
        radius	= radius / Reconstruction::ROBUST_SCALE;
    }
}