use of boofcv.alg.geo.selfcalib.RefineDualQuadraticAlgebraicError.CameraState in project BoofCV by lessthanoptimal.
the class TestRefineDualQuadraticAlgebraicError method encode_decode.
@Test
void encode_decode() {
var alg = new RefineDualQuadraticAlgebraicError();
for (int i = 0; i < 10; i++) {
alg.priorCameras.grow().setTo(400 + i, 1.0 + i / 20.0, 340, 400);
}
alg.cameras.resize(alg.priorCameras.size);
double[] parameters = new double[(1 + 1 + 2) * 10 + 3];
Point3D_F64 p = new Point3D_F64(planeAtInfinity.get(0), planeAtInfinity.get(1), planeAtInfinity.get(2));
alg.encodeParameters(p, alg.priorCameras, parameters);
p.setTo(0, 0, 0);
alg.decodeParameters(parameters, alg.cameras, p);
for (int cameraIdx = 0; cameraIdx < alg.cameras.size; cameraIdx++) {
CameraState found = alg.cameras.get(cameraIdx);
CameraState expected = alg.cameras.get(cameraIdx);
assertEquals(expected.fx, found.fx);
assertEquals(expected.aspectRatio, found.aspectRatio);
assertEquals(expected.cx, found.cx);
assertEquals(expected.cy, found.cy);
}
assertEquals(planeAtInfinity.get(0), p.x);
assertEquals(planeAtInfinity.get(1), p.y);
assertEquals(planeAtInfinity.get(2), p.z);
}
use of boofcv.alg.geo.selfcalib.RefineDualQuadraticAlgebraicError.CameraState in project BoofCV by lessthanoptimal.
the class TestRefineDualQuadraticAlgebraicError method checkRefine.
private void checkRefine(RefineDualQuadraticAlgebraicError alg, List<CameraPinhole> expected, List<CameraPinhole> noisy, double tol) {
// alg.setVerbose(System.out, null);
renderGood(expected);
setState(alg, noisy, planeAtInfinity.get(0), planeAtInfinity.get(1), planeAtInfinity.get(2));
assertTrue(alg.refine());
List<CameraState> found = alg.getCameras().toList();
// checking against size of noisy, since noisy is number of cameras
assertEquals(noisy.size(), found.size());
// estimate gets worse
for (int i = 0; i < noisy.size(); i++) {
CameraPinhole e = expected.get(i);
CameraState f = found.get(i);
if (alg.isKnownAspect()) {
assertEquals(e.fx, f.fx, tol);
assertEquals(e.fy / e.fx, f.aspectRatio, 0.01);
} else {
assertEquals(e.fx, f.fx, tol);
assertEquals(e.fy / e.fx, f.aspectRatio, 0.05);
}
if (alg.isKnownPrinciplePoint()) {
assertEquals(e.cx, f.cx, UtilEjml.TEST_F64_SQ);
assertEquals(e.cy, f.cy, UtilEjml.TEST_F64_SQ);
} else {
assertEquals(e.cx, f.cx, tol);
assertEquals(e.cy, f.cy, tol);
}
}
}
use of boofcv.alg.geo.selfcalib.RefineDualQuadraticAlgebraicError.CameraState in project BoofCV by lessthanoptimal.
the class ProjectiveToMetricCameraDualQuadratic method refineCamerasAlgebraic.
/**
* This refines intrinsic parameters by minimizing algebraic error. If anything goes wrong it doesn't update
* the intrinsics. Also updates the rectifying homography.
*/
void refineCamerasAlgebraic(List<ElevateViewInfo> views, List<DMatrixRMaj> cameraMatrices, int numCameras) {
// Refiner can't handle non-zero skew yet
if (!selfCalib.zeroSkew) {
if (verbose != null)
verbose.println("Skipping refine since skew is not zero");
return;
}
// Just skip everything if it has been turned off
if (refiner.converge.maxIterations <= 0)
return;
// Sanity check the P0 is implicit
BoofMiscOps.checkEq(views.size(), cameraMatrices.size() + 1);
// Make sure refiner applies the same constraints that the linear estimator applies
refiner.knownAspect = selfCalib.isKnownAspect();
refiner.knownPrinciplePoint = true;
// Configure the refiner. If multiple views use the same camera this constraint is applied
refiner.initialize(numCameras, views.size());
DMatrix3 planeAtInfinity = selfCalib.getPlaneAtInfinity();
refiner.setPlaneAtInfinity(planeAtInfinity.a1, planeAtInfinity.a2, planeAtInfinity.a3);
for (int cameraIdx = 0; cameraIdx < numCameras; cameraIdx++) {
CameraPinhole merged = workCameras.get(cameraIdx);
refiner.setCamera(cameraIdx, merged.fx, merged.cx, merged.cy, merged.fy / merged.fx);
}
for (int viewIdx = 0; viewIdx < views.size(); viewIdx++) {
if (viewIdx == 0)
refiner.setProjective(0, P1);
else
refiner.setProjective(viewIdx, cameraMatrices.get(viewIdx - 1));
refiner.setViewToCamera(viewIdx, views.get(viewIdx).cameraID);
}
// Refine and change nothing if it fails
if (!refiner.refine()) {
if (verbose != null)
verbose.println("Refine failed! Ignoring results");
return;
}
if (verbose != null) {
for (int i = 0; i < numCameras; i++) {
CameraState refined = refiner.getCameras().get(i);
verbose.printf("refined[%d] fx=%.1f fy=%.1f\n", i, refined.fx, refined.fx * refined.aspectRatio);
}
}
// Save the refined intrinsic parameters
for (int i = 0; i < views.size(); i++) {
ElevateViewInfo info = views.get(i);
CameraState refined = refiner.getCameras().get(info.cameraID);
CameraPinhole estimated = workCameras.get(info.cameraID);
estimated.fx = refined.fx;
estimated.fy = refined.aspectRatio * refined.fx;
// refiner doesn't support non-zero skew yet
}
// Update rectifying homography using the new parameters
// NOTE: This formulation of H requires P1=[I|0] which is true in this case
PerspectiveOps.pinholeToMatrix(workCameras.get(views.get(0).cameraID), K);
MultiViewOps.canonicalRectifyingHomographyFromKPinf(K, refiner.planeAtInfinity, H);
}
Aggregations