use of boofcv.alg.structure.PairwiseImageGraph.Motion in project BoofCV by lessthanoptimal.
the class ProjectiveInitializeAllCommon method findRemainingCameraMatrices.
/**
* Uses the triangulated points and observations in the root view to estimate the camera matrix for
* all the views which are remaining. We are assuming that outliers have already been removed.
*
* @param seedConnIdx (Input) Specifies which connections in 'seed.connections' are to be used.
* @return true if successful or false if not
*/
boolean findRemainingCameraMatrices(LookUpSimilarImages dbSimilar, LookUpCameraInfo dbCams, View seed, DogArray_I32 seedConnIdx) {
int numInliers = inlierIndexes.get(0).size;
BoofMiscOps.checkTrue(numInliers == utils.inliersThreeView.size());
// Look up the 3D coordinates of features from the scene's structure previously computed
// points in 3D
points3D.reset();
for (int i = 0; i < utils.structure.points.size; i++) {
utils.structure.points.data[i].get(points3D.grow());
}
// contains associated pairs of pixel observations
// save a call to db by using the previously loaded points for the seed view
assocPixel.resize(numInliers);
for (int i = 0; i < numInliers; i++) {
// inliers from triple RANSAC
// each of these inliers was declared a feature in the world reference frame
assocPixel.get(i).p1.setTo(utils.inliersThreeView.get(i).p1);
}
var cameraMatrix = new DMatrixRMaj(3, 4);
for (int motionIdx = 0; motionIdx < seedConnIdx.size; motionIdx++) {
int connectionIdx = seedConnIdx.get(motionIdx);
// skip views already in the scene's structure
if (connectionIdx == selectedTriple[0] || connectionIdx == selectedTriple[1])
continue;
Motion edge = seed.connections.get(connectionIdx);
View viewI = edge.other(seed);
// Lookup pixel locations of features in the connected view
dbCams.lookupCalibration(viewI.id, utils.priorCamB);
dbSimilar.lookupPixelFeats(viewI.id, utils.featsB);
BoofMiscOps.offsetPixels(utils.featsB.toList(), -utils.priorCamB.cx, -utils.priorCamB.cy);
if (!computeCameraMatrix(seed, edge, utils.featsB, cameraMatrix)) {
if (verbose != null)
verbose.println("Pose estimator failed! view='" + viewI.id + "'");
// TODO skip over this view instead
return false;
}
if (verbose != null)
verbose.println("Expanded initial scene to include view='" + viewI.id + "'");
// ---------------------------------------------------------------------------
// Add all the information from this view to SBA data structure
int indexSbaView = motionIdx + 1;
// image information and found camera matrix
dbCams.lookupViewShape(edge.other(seed).id, shape);
utils.structure.setView(indexSbaView, false, cameraMatrix, shape.width, shape.height);
// observation of features
SceneObservations.View sbaObsView = utils.observations.getView(indexSbaView);
checkTrue(sbaObsView.size() == 0, "Must be reset to initial state first");
for (int i = 0; i < numInliers; i++) {
Point2D_F64 p = assocPixel.get(i).p2;
sbaObsView.add(i, (float) p.x, (float) p.y);
}
viewsByStructureIndex.set(indexSbaView, viewI);
}
return true;
}
use of boofcv.alg.structure.PairwiseImageGraph.Motion in project BoofCV by lessthanoptimal.
the class TestExpandByOneView method selectTwoConnections.
/**
* Creates a more complex scenario and sees if it selects the correct two views
*/
@Test
void selectTwoConnections() {
var working = new SceneWorkingGraph();
var graph = new PairwiseImageGraph();
SceneWorkingGraph.Camera camera = working.addCamera(2);
View seed = graph.createNode("A");
for (int i = 0; i < 6; i++) {
View viewI = graph.createNode("" + i);
// make sure src/dst is handled correctly
Motion mA = i % 2 == 0 ? graph.connect(seed, viewI) : graph.connect(viewI, seed);
// All have the same score so that the connections between the other two is what decides the winner
mA.score3D = 2.0;
mA.is3D = true;
working.addView(viewI, camera);
}
View viewB = seed.connection(1);
View viewC = seed.connection(2);
View viewD = seed.connection(3);
Motion connBC = graph.connect(viewB, viewC);
Motion connBD = graph.connect(viewD, viewB);
connBD.is3D = connBC.is3D = true;
connBC.score3D = 1.2;
// this is the more desirable connection
connBD.score3D = 1.3;
var alg = new ChildProjectiveExpandByOneView();
alg.workGraph = working;
var found = new ArrayList<Motion>();
assertTrue(alg.selectTwoConnections(seed, found));
assertTrue(found.contains(seed.connections.get(1)));
assertTrue(found.contains(seed.connections.get(3)));
}
use of boofcv.alg.structure.PairwiseImageGraph.Motion in project BoofCV by lessthanoptimal.
the class TestProjectiveInitializeAllCommon method selectInitialTriplet.
@Test
void selectInitialTriplet() {
// Set up a view graph with several valid options
var seed = new View();
for (int i = 0; i < 6; i++) {
View view = new View();
Motion motion = new Motion();
// sanity check that it handles src/dst correctly
motion.src = i % 2 == 0 ? seed : view;
motion.dst = i % 2 == 0 ? view : seed;
motion.score3D = (100 + i) / 50.0;
seed.connections.add(motion);
}
// need to make a complete loop
for (int i = 1; i < 6; i++) {
Motion motion = new Motion();
motion.src = seed.connections.get(i - 1).other(seed);
motion.dst = seed.connections.get(i).other(seed);
motion.score3D = 50.0 / 30.0;
motion.src.connections.add(motion);
motion.dst.connections.add(motion);
}
// Select the results
var alg = new ProjectiveInitializeAllCommon();
// skip one to see if it uses this list
DogArray_I32 edgeIdxs = DogArray_I32.array(0, 2, 3, 4, 5);
int[] selected = new int[2];
alg.selectInitialTriplet(seed, edgeIdxs, selected);
assertEquals(4, selected[0]);
assertEquals(5, selected[1]);
}
use of boofcv.alg.structure.PairwiseImageGraph.Motion in project BoofCV by lessthanoptimal.
the class TestProjectiveInitializeAllCommon method removeConnectionOutliers.
private void removeConnectionOutliers(View seed, DogArray_I32 seedFeatsIdx) {
for (Motion m : seed.connections.toList()) {
// mark all indexes which are inliers
boolean isSrc = m.src == seed;
boolean[] inlier = new boolean[seed.totalObservations];
for (AssociatedIndex a : m.inliers.toList()) {
inlier[isSrc ? a.src : a.dst] = true;
}
// remove the outliers
for (int i = 0; i < inlier.length; i++) {
if (!inlier[i]) {
int idx = seedFeatsIdx.indexOf(i);
if (idx >= 0)
seedFeatsIdx.remove(idx);
}
}
}
}
use of boofcv.alg.structure.PairwiseImageGraph.Motion in project BoofCV by lessthanoptimal.
the class TestProjectiveInitializeAllCommon method scoreTripleView_NotCircle.
/**
* Give it a set of three views which are not mutually connected in a complete circle
*/
@Test
void scoreTripleView_NotCircle() {
var alg = new ProjectiveInitializeAllCommon();
View seedA = new View();
View viewB = new View();
View viewC = new View();
Motion motionAB = new Motion();
motionAB.src = seedA;
motionAB.dst = viewB;
// give it an excellent 3D score
motionAB.score3D = 1000;
Motion motionAC = new Motion();
motionAC.src = viewC;
// src/dst shouldn't matter. bonus check
motionAC.dst = seedA;
// give it an excellent 3D score
motionAC.score3D = 1000;
seedA.connections.add(motionAB);
viewB.connections.add(motionAB);
seedA.connections.add(motionAC);
viewC.connections.add(motionAC);
// No connection B to C is made
assertEquals(0.0, alg.scoreTripleView(seedA, viewB, viewC), UtilEjml.TEST_F64);
}
Aggregations