use of boofcv.alg.structure.PairwiseImageGraph.View 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.View in project BoofCV by lessthanoptimal.
the class TestProjectiveInitializeAllCommon method createObservationsForBundleAdjustment.
@Test
void createObservationsForBundleAdjustment() {
var dbSimilar = new MockLookupSimilarImages(5, 0xDEADBEEF);
var dbCams = new MockLookUpCameraInfo(dbSimilar.intrinsic);
PairwiseImageGraph graph = dbSimilar.graph;
View seed = graph.nodes.get(0);
// which edges in the first view should be considered
DogArray_I32 motionIndexes = DogArray_I32.array(0, 2, 3);
var alg = new ProjectiveInitializeAllCommon();
alg.utils.dbSimilar = dbSimilar;
alg.utils.dbCams = dbCams;
alg.utils.seed = seed;
// ------------------------------ Initialize internal data structures
// make every other feature an inlier
alg.seedToStructure.resize(dbSimilar.feats3D.size());
alg.seedToStructure.fill(-1);
DogArray_I32 inlierToSeed = alg.inlierIndexes.grow();
for (int i = 0; i < dbSimilar.feats3D.size(); i += 2) {
alg.seedToStructure.data[i] = inlierToSeed.size;
inlierToSeed.add(i);
}
dbSimilar.lookupPixelFeats(seed.id, alg.utils.featsA);
// Call the function being tested
// allocate for rest of the views
alg.inlierIndexes.resize(motionIndexes.size + 1);
alg.createObservationsForBundleAdjustment(motionIndexes);
SceneObservations found = alg.utils.observations;
found.checkOneObservationPerView();
// Check to see if there's the expected number of views
assertFalse(found.hasRigid());
// seed + 3 connected views
assertEquals(4, found.views.size);
for (int i = 0; i < 4; i++) {
SceneObservations.View view = found.views.get(i);
assertEquals(inlierToSeed.size, view.size());
for (int j = 0; j < view.size(); j++) {
// crude sanity check on the index
assertTrue(view.getPointId(j) < inlierToSeed.size);
}
}
// Not doing a detailed check of the values since that will be very complex
}
use of boofcv.alg.structure.PairwiseImageGraph.View 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.View in project BoofCV by lessthanoptimal.
the class TestProjectiveInitializeAllCommon method perfect_connections_3_to_5.
/**
* Perfect scene with 3 to 5 connections
*/
@Test
void perfect_connections_3_to_5() {
var alg = new ProjectiveInitializeAllCommon();
for (int numConnections = 3; numConnections <= 6; numConnections++) {
// do a few trials since things are randomized to shake out more bugs potentially
for (int trial = 0; trial < 3; trial++) {
var dbSimilar = new MockLookupSimilarImagesRealistic().pathCircle(6, 2);
var dbCams = new MockLookUpCameraInfo(dbSimilar.intrinsic);
List<String> viewIdStr = dbSimilar.getImageIDs();
PairwiseImageGraph graph = dbSimilar.createPairwise();
View seed = graph.nodes.get(0);
// randomly select the connections
var seedConnIdx = new DogArray_I32();
for (int i = 0; i < seed.connections.size; i++) {
seedConnIdx.add(i);
}
for (int i = 0; i < seed.connections.size - numConnections; i++) {
seedConnIdx.remove(rand.nextInt(seedConnIdx.size));
}
// order should not matter
PrimitiveArrays.shuffle(seedConnIdx.data, 0, seedConnIdx.size, rand);
// index of connected views in ground truth
var connectedViewidx = new DogArray_I32();
for (int i = 0; i < seedConnIdx.size; i++) {
String id = seed.connections.get(seedConnIdx.get(i)).other(seed).id;
connectedViewidx.add(viewIdStr.indexOf(id));
}
// in this specific scenario all features are visible by all frames
var seedFeatsIdx = DogArray_I32.range(0, dbSimilar.numFeatures);
// however not all features are in the inlier set. Remove all features not in inlier set
removeConnectionOutliers(seed, seedFeatsIdx);
// order should not matter
PrimitiveArrays.shuffle(seedFeatsIdx.data, 0, seedFeatsIdx.size, rand);
// Reconstruct the projective scene
assertTrue(alg.projectiveSceneN(dbSimilar, dbCams, seed, seedFeatsIdx, seedConnIdx));
// test results
checkReconstruction(alg, dbSimilar, seedConnIdx, reprojectionTol);
}
}
}
use of boofcv.alg.structure.PairwiseImageGraph.View in project BoofCV by lessthanoptimal.
the class TestProjectiveInitializeAllCommon method checkCameraMatrices.
/**
* Check camera matrices directly by computing a matrix which allows direct comparision of the two sets
*/
private void checkCameraMatrices(ProjectiveInitializeAllCommon alg, MockLookupSimilarImagesRealistic db) {
List<DMatrixRMaj> listA = new ArrayList<>();
List<DMatrixRMaj> listB = new ArrayList<>();
// Undo the shift in pixel coordinates
DMatrixRMaj M = CommonOps_DDRM.identity(3);
M.set(0, 2, db.intrinsic.cx);
M.set(1, 2, db.intrinsic.cy);
List<String> viewIds = BoofMiscOps.collectList(db.views, v -> v.id);
for (int i = 0; i < 3; i++) {
View view = alg.getPairwiseGraphViewByStructureIndex(i);
DMatrixRMaj P = new DMatrixRMaj(3, 4);
CommonOps_DDRM.mult(M, alg.utils.structure.views.get(i).worldToView, P);
listA.add(P);
int viewDbIdx = viewIds.indexOf(view.id);
listB.add(db.views.get(viewDbIdx).camera);
}
DMatrixRMaj H = new DMatrixRMaj(4, 4);
CompatibleProjectiveHomography compatible = new CompatibleProjectiveHomography();
assertTrue(compatible.fitCameras(listA, listB, H));
DMatrixRMaj found = new DMatrixRMaj(3, 4);
for (int i = 0; i < listA.size(); i++) {
CommonOps_DDRM.mult(listA.get(i), H, found);
DMatrixRMaj expected = listB.get(i);
double scale = expected.get(0, 0) / found.get(0, 0);
CommonOps_DDRM.scale(scale, found);
assertTrue(MatrixFeatures_DDRM.isEquals(expected, found, matrixTol));
}
}
Aggregations