/** Test against perfectly matched and a little bit of noise */ @Test public void test2D() { for (double noise = 0; noise <= 0.01; noise += 0.01) { // can only correct small changes Se2_F64 tran = new Se2_F64(0.01, -0.02, 0.01); List<Point2D_F64> srcPts = UtilPoint2D_F64.random(-10, 10, 30, rand); List<Point2D_F64> srcOrig = UtilPoint2D_F64.copy(srcPts); List<Point2D_F64> modelPts = new ArrayList<Point2D_F64>(); for (Point2D_F64 p : srcPts) { modelPts.add(SePointOps_F64.transform(tran, p, null)); } // add noise UtilPoint2D_F64.noiseNormal(modelPts, noise, rand); PointModel<Point2D_F64> model = new PointModel<Point2D_F64>(modelPts); StoppingCondition stop = new StoppingCondition(10, 0.1 * noise / srcPts.size() + 1e-8); IterativeClosestPoint<Se2_F64, Point2D_F64> alg = new IterativeClosestPoint<Se2_F64, Point2D_F64>(stop, new MotionSe2PointSVD_F64()); alg.setModel(model); alg.process(srcPts); Se2_F64 foundTran = alg.getPointsToModel(); checkTransform(srcOrig, modelPts, foundTran, noise * 10 + 1e-8); } }
/** * Returns the closest point on the contour to the provided point in space * * @return index of closest point */ int closestPoint(Point2D_F64 target) { double bestDistance = Double.MAX_VALUE; int bestIndex = -1; for (int i = 0; i < contour.size(); i++) { Point2D_I32 c = contour.get(i); double d = UtilPoint2D_F64.distanceSq(target.x, target.y, c.x, c.y); if (d < bestDistance) { bestDistance = d; bestIndex = i; } } return bestIndex; }
@Test public void noiseless() { Affine2D_F64 tran = new Affine2D_F64(2, -4, 0.3, 1.1, 0.93, -3); List<Point2D_F64> from = UtilPoint2D_F64.random(-10, 10, 30, rand); List<Point2D_F64> to = new ArrayList<Point2D_F64>(); for (Point2D_F64 p : from) { to.add(AffinePointOps.transform(tran, p, null)); } MotionAffinePoint2D_F64 alg = new MotionAffinePoint2D_F64(); assertTrue(alg.process(from, to)); Affine2D_F64 tranFound = alg.getMotion(); checkTransform(from, to, tranFound, GrlConstants.DOUBLE_TEST_TOL); }