use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.
the class GenericCalibrationGrid method observations.
public static CalibrationObservation observations(Se3_F64 motion, List<Point2D_F64> obs2D) {
CalibrationObservation ret = new CalibrationObservation();
for (int i = 0; i < obs2D.size(); i++) {
Point2D_F64 p2 = obs2D.get(i);
Point3D_F64 p3 = new Point3D_F64(p2.x, p2.y, 0);
Point3D_F64 t = SePointOps_F64.transform(motion, p3, null);
ret.add(new Point2D_F64(t.x / t.z, t.y / t.z), i);
}
return ret;
}
use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.
the class GenericCalibrationGrid method createObservations.
/**
* Creates a set of observed points in pixel coordinates given zhang parameters and a calibration
* grid.
*/
public static List<CalibrationObservation> createObservations(Zhang99AllParam config, List<Point2D_F64> grid) {
List<CalibrationObservation> ret = new ArrayList<>();
Point3D_F64 cameraPt = new Point3D_F64();
Point2D_F64 pixelPt = new Point2D_F64();
Zhang99IntrinsicParam intrinsic = config.getIntrinsic();
for (Zhang99AllParam.View v : config.views) {
CalibrationObservation set = new CalibrationObservation();
Se3_F64 se = new Se3_F64();
ConvertRotation3D_F64.rodriguesToMatrix(v.rotation, se.getR());
se.T = v.T;
for (int i = 0; i < grid.size(); i++) {
Point2D_F64 grid2D = grid.get(i);
Point3D_F64 grid3D = new Point3D_F64(grid2D.x, grid2D.y, 0);
// Put the point in the camera's reference frame
SePointOps_F64.transform(se, grid3D, cameraPt);
// project and distort the point
intrinsic.project(cameraPt, pixelPt);
set.add(pixelPt, i);
}
ret.add(set);
}
return ret;
}
use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.
the class GenericCalibrationZhang99 method applyDistortion.
@Test
public void applyDistortion() {
Point2D_F64 n = new Point2D_F64(0.05, -0.1);
double[] radial = new double[] { 0.1 };
double t1 = 0.034, t2 = 0.34;
Point2D_F64 distorted = new Point2D_F64();
double r2 = n.x * n.x + n.y * n.y;
distorted.x = n.x + radial[0] * r2 * n.x + 2 * t1 * n.x * n.y + t2 * (r2 + 2 * n.x * n.x);
distorted.y = n.y + radial[0] * r2 * n.y + t1 * (r2 + 2 * n.y * n.y) + 2 * t2 * n.x * n.y;
CalibrationPlanarGridZhang99.applyDistortion(n, radial, t1, t2);
assertEquals(distorted.x, n.x, 1e-8);
assertEquals(distorted.y, n.y, 1e-8);
}
use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.
the class TestZhang99ComputeTargetHomography method basicTest.
public void basicTest(boolean removeAFew) {
// create a grid an apply an arbitrary transform to it
List<Point2D_F64> layout = GenericCalibrationGrid.standardLayout();
DMatrixRMaj R = ConvertRotation3D_F64.eulerToMatrix(EulerType.XYZ, 0.02, -0.05, 0.01, null);
Vector3D_F64 T = new Vector3D_F64(0, 0, -1000);
Se3_F64 motion = new Se3_F64(R, T);
CalibrationObservation observations = GenericCalibrationGrid.observations(motion, layout);
if (removeAFew) {
for (int i = 0; i < 6; i++) {
observations.points.remove(5);
}
}
// compute the homography
Zhang99ComputeTargetHomography alg = new Zhang99ComputeTargetHomography(layout);
assertTrue(alg.computeHomography(observations));
DMatrixRMaj H = alg.getHomography();
// test this homography property: x2 = H*x1
for (int i = 0; i < observations.size(); i++) {
int gridIndex = observations.get(i).index;
Point2D_F64 p = observations.get(i);
Point2D_F64 a = GeometryMath_F64.mult(H, layout.get(gridIndex), new Point2D_F64());
double diff = a.distance(p);
assertEquals(0, diff, 1e-8);
}
}
use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.
the class TestZhang99OptimizationJacobian method compareToNumerical.
private void compareToNumerical(boolean assumeZeroSkew, boolean includeTangential) {
Zhang99AllParam param = GenericCalibrationGrid.createStandardParam(TestPinholeCalibrationZhang99.createStandard(assumeZeroSkew, includeTangential, 2, rand), 3, rand);
// give it larger values that will generate a larger derivative and pass the unit test
CameraPinholeRadial p = param.getIntrinsic().getCameraModel();
p.radial[0] = 0.2;
p.radial[1] = 0.25;
p.t1 = 0.05;
p.t2 = 0.07;
List<Point2D_F64> gridPts = CalibrationDetectorSquareGrid.createLayout(3, 2, 30, 30);
List<CalibrationObservation> observations = new ArrayList<>();
for (int i = 0; i < param.views.length; i++) {
observations.add(estimate(param, param.views[i], gridPts));
}
if (partial) {
for (int i = 0; i < observations.size(); i++) {
CalibrationObservation c = observations.get(i);
for (int j = 0; j < 5; j++) {
c.points.remove(3 * i);
}
}
}
double[] dataParam = new double[param.numParameters()];
param.convertToParam(dataParam);
Zhang99OptimizationFunction func = new Zhang99OptimizationFunction(param.copy(), gridPts, observations);
Zhang99OptimizationJacobian alg = new Zhang99OptimizationJacobian((CalibParamPinholeRadial) param.getIntrinsic(), observations, gridPts);
// Why does the tolerance need to be so crude? Is there a fundamental reason for this?
double tol = includeTangential ? 0.05 : 0.01;
// DerivativeChecker.jacobianPrintR(func, alg, dataParam, tol);
assertTrue(DerivativeChecker.jacobianR(func, alg, dataParam, tol));
}
Aggregations