Пример #1
0
bool Cone::LeastSquaresFit(const PointCloud &pc,
	MiscLib::Vector< size_t >::const_iterator begin,
	MiscLib::Vector< size_t >::const_iterator end)
{
	bool retVal = LeastSquaresFit(GfxTL::IndexIterate(begin, pc.begin()),
		GfxTL::IndexIterate(end, pc.begin()));
	return retVal;
}
Пример #2
0
/* Estimate a transform between two sets of keypoints */
std::vector<int> EstimateTransform(const std::vector<Keypoint> &k1, 
				   const std::vector<Keypoint> &k2, 
				   const std::vector<KeypointMatch> &matches, 
				   MotionModel mm,
				   int nRANSAC, double RANSACthresh, 
				   double *Mout) 
{
    int min_matches = -1;
    switch (mm) {
	case MotionRigid:
	    min_matches = 3;
	    break;
	case MotionHomography:
	    min_matches = 4;
	    break;
    }

    int *match_idxs = new int[min_matches];

    int num_matches = (int) matches.size();
    int max_inliers = 0;
    double Mbest[9];
    
    if (num_matches < min_matches) {
	std::vector<int> empty;
	printf("Cannot estimate rigid transform\n");
	return empty;
    }

    v3_t *r_pts = new v3_t[min_matches];
    v3_t *l_pts = new v3_t[min_matches];
    double *weight = new double[min_matches];

    for (int round = 0; round < nRANSAC; round++) {
	for (int i = 0; i < min_matches; i++) {
	    bool found;
	    int idx;
	    
	    do {
		found = true;
		idx = rand() % num_matches;
		
		for (int j = 0; j < i; j++) {
		    if (match_idxs[j] == idx) {
			found = false;
			break;
		    }
		}
	    } while (!found);

	    match_idxs[i] = idx;
	}

	/* Solve for the motion */
		
	for (int i = 0; i < min_matches; i++) {
	    int idx1 = matches[match_idxs[i]].m_idx1;
	    int idx2 = matches[match_idxs[i]].m_idx2;
	    
	    Vx(l_pts[i]) = k1[idx1].m_x;
	    Vy(l_pts[i]) = k1[idx1].m_y;
	    Vz(l_pts[i]) = 1.0;
		    
	    Vx(r_pts[i]) = k2[idx2].m_x;
	    Vy(r_pts[i]) = k2[idx2].m_y;
	    Vz(r_pts[i]) = 1.0;

	    weight[i] = 1.0;
	}

	double Mcurr[9];

	switch (mm) {
	    case MotionRigid: {
		double R[9], T[9], Tout[9], scale;
		align_horn(min_matches, r_pts, l_pts, R, T, Tout, &scale, weight);
		memcpy(Mcurr, Tout, 9 * sizeof(double));
		break;
	    }
		
	    case MotionHomography: {
		align_homography(min_matches, r_pts, l_pts, Mcurr, 0);
		break;
	    }
	}
		

	std::vector<int> inliers;
	int num_inliers = CountInliers(k1, k2, matches, Mcurr, 
				       RANSACthresh, inliers);

	if (num_inliers > max_inliers) {
	    max_inliers = num_inliers;
	    memcpy(Mbest, Mcurr, 9 * sizeof(double));
	}
    }

    std::vector<int> inliers;
    CountInliers(k1, k2, matches, Mbest, RANSACthresh, inliers);
    memcpy(Mout, Mbest, 9 * sizeof(double));
    LeastSquaresFit(k1, k2, matches, mm, inliers, Mout);

    // memcpy(Mout, Mbest, 9 * sizeof(double));

    delete [] match_idxs;
    delete [] r_pts;
    delete [] l_pts;
    delete [] weight;

    return inliers;
}
Пример #3
0
sBool sBSpline::FitCurveImpl(const Sample *samples,sInt nSamples,sF32 maxError,sInt maxRefinements)
{
    sArray<sF32> NewKnots;
    sBool Subdivided = sFALSE;

    // Initial fit
    LeastSquaresFit(samples,nSamples);

    // Refine as necessary
    NewKnots.Init(Knots.Count);

    while(maxRefinements-- > 0)
    {
        // Calculate new knot vector: Setup
        NewKnots.Count = 0;
        const Sample *sample = samples;
        const Sample *sampleEnd = samples + nSamples;
        Subdivided = sFALSE;

        *NewKnots.Add() = Knots[0];

        // Go through knot intervals, measuring error and subdiving as necesarry
        for(sInt i=1; i<Knots.Count; i++)
        {
            if(Knots[i] != Knots[i-1]) // nonempty interval
            {
                // Measure max. error (currently without derivatives)
                sF32 error = 0.0f;

                while(sample < sampleEnd && sample->Time < Knots[i])
                {
                    if(sample->Type == 0) // only direct values
                        error = sMax<sF32>(error,sFAbs(sample->Value - Evaluate(sample->Time)));

                    sample++;
                }

                // Add new knot in middle if error bigger than threshold
                if(error >= maxError)
                {
                    *NewKnots.Add() = (Knots[i-1] + Knots[i]) * 0.5f;
                    Subdivided = sTRUE;
                }
            }

            // Add old knot value in any case
            *NewKnots.Add() = Knots[i];
        }

        // If not subdivided, we're done, else compute new approximation
        // and iterate
        if(!Subdivided)
            break;
        else
        {
            Knots.Swap(NewKnots);
            Values.Resize(Knots.Count);
            LeastSquaresFit(samples,nSamples);
        }
    }

    NewKnots.Exit();
    return !Subdivided;
}