/** Give it a grid and see if it computed a legitimate homography */ @Test public void basicTest() { // create a grid an apply an arbitrary transform to it PlanarCalibrationTarget config = GenericCalibrationGrid.createStandardConfig(); DenseMatrix64F R = RotationMatrixGenerator.eulerXYZ(0.02, -0.05, 0.01, null); Vector3D_F64 T = new Vector3D_F64(0, 0, -1000); Se3_F64 motion = new Se3_F64(R, T); List<Point2D_F64> observations = GenericCalibrationGrid.observations(motion, config); // compute the homography Zhang99ComputeTargetHomography alg = new Zhang99ComputeTargetHomography(config); assertTrue(alg.computeHomography(observations)); DenseMatrix64F H = alg.getHomography(); // test this homography property: x2 = H*x1 List<Point2D_F64> gridPoints = config.points; for (int i = 0; i < observations.size(); i++) { Point2D_F64 a = GeometryMath_F64.mult(H, gridPoints.get(i), new Point2D_F64()); double diff = a.distance(observations.get(i)); assertEquals(0, diff, 1e-8); } }
/** The two sets of points match perfectly and with a little bit of noise */ @Test public void test3D() { for (double noise = 0; noise <= 0.01; noise += 0.01) { // can only correct small changes DenseMatrix64F R = RotationMatrixGenerator.eulerXYZ(0.01, -0.002, 0.03, null); Vector3D_F64 T = new Vector3D_F64(0.02, 0.03, 0.01); Se3_F64 tran = new Se3_F64(R, T); List<Point3D_F64> srcPts = UtilPoint3D_F64.random(-10, 10, 30, rand); List<Point3D_F64> srcOrig = UtilPoint3D_F64.copy(srcPts); List<Point3D_F64> modelPts = new ArrayList<Point3D_F64>(); for (Point3D_F64 p : srcPts) { modelPts.add(SePointOps_F64.transform(tran, p, null)); } // add noise UtilPoint3D_F64.noiseNormal(modelPts, noise, rand); PointModel<Point3D_F64> model = new PointModel<Point3D_F64>(modelPts); StoppingCondition stop = new StoppingCondition(10, 0.1 * noise / srcPts.size() + 1e-8); IterativeClosestPoint<Se3_F64, Point3D_F64> alg = new IterativeClosestPoint<Se3_F64, Point3D_F64>(stop, new MotionSe3PointSVD_F64()); alg.setModel(model); alg.process(srcPts); Se3_F64 foundTran = alg.getPointsToModel(); checkTransform(srcOrig, modelPts, foundTran, noise * 10 + 1e-8); } }