Skip to content

Commit 9f70659

Browse files
committed
Correctly invert two-view geometries when writing swapped image pair to database
1 parent 885d239 commit 9f70659

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

src/base/database.cc

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -516,15 +516,15 @@ TwoViewGeometry Database::ReadTwoViewGeometry(const image_t image_id1,
516516

517517
SQLITE3_CALL(sqlite3_reset(sql_stmt_read_two_view_geometry_));
518518

519-
if (SwapImagePair(image_id1, image_id2)) {
520-
SwapFeatureMatchesBlob(&blob);
521-
}
522-
523519
two_view_geometry.inlier_matches = FeatureMatchesFromBlob(blob);
524520
two_view_geometry.F.transposeInPlace();
525521
two_view_geometry.E.transposeInPlace();
526522
two_view_geometry.H.transposeInPlace();
527523

524+
if (SwapImagePair(image_id1, image_id2)) {
525+
two_view_geometry.Invert();
526+
}
527+
528528
return two_view_geometry;
529529
}
530530

@@ -695,26 +695,32 @@ void Database::WriteTwoViewGeometry(
695695
SQLITE3_CALL(
696696
sqlite3_bind_int64(sql_stmt_write_two_view_geometry_, 1, pair_id));
697697

698-
// Important: the swapped data must live until the query is executed.
699-
FeatureMatchesBlob inlier_matches =
700-
FeatureMatchesToBlob(two_view_geometry.inlier_matches);
698+
const TwoViewGeometry* two_view_geometry_ptr = &two_view_geometry;
699+
700+
// Invert the two-view geometry if the image pair has to be swapped.
701+
std::unique_ptr<TwoViewGeometry> swapped_two_view_geometry;
701702
if (SwapImagePair(image_id1, image_id2)) {
702-
SwapFeatureMatchesBlob(&inlier_matches);
703+
swapped_two_view_geometry.reset(new TwoViewGeometry());
704+
*swapped_two_view_geometry = two_view_geometry;
705+
swapped_two_view_geometry->Invert();
706+
two_view_geometry_ptr = swapped_two_view_geometry.get();
703707
}
704708

709+
const FeatureMatchesBlob inlier_matches =
710+
FeatureMatchesToBlob(two_view_geometry_ptr->inlier_matches);
705711
WriteDynamicMatrixBlob(sql_stmt_write_two_view_geometry_, inlier_matches, 2);
706712

707713
SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_write_two_view_geometry_, 5,
708-
two_view_geometry.config));
714+
two_view_geometry_ptr->config));
709715

710716
// Transpose the matrices to obtain row-major data layout.
711717
// Important: Do not move these objects inside the if-statement, because
712718
// the objects must live until `sqlite3_step` is called on the statement.
713-
const Eigen::Matrix3d Ft = two_view_geometry.F.transpose();
714-
const Eigen::Matrix3d Et = two_view_geometry.E.transpose();
715-
const Eigen::Matrix3d Ht = two_view_geometry.H.transpose();
719+
const Eigen::Matrix3d Ft = two_view_geometry_ptr->F.transpose();
720+
const Eigen::Matrix3d Et = two_view_geometry_ptr->E.transpose();
721+
const Eigen::Matrix3d Ht = two_view_geometry_ptr->H.transpose();
716722

717-
if (two_view_geometry.inlier_matches.size() > 0) {
723+
if (two_view_geometry_ptr->inlier_matches.size() > 0) {
718724
WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Ft, 6);
719725
WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Et, 7);
720726
WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Ht, 8);

src/base/database_test.cc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ BOOST_AUTO_TEST_CASE(TestMatches) {
304304
BOOST_CHECK_EQUAL(database.NumMatches(), 0);
305305
}
306306

307-
BOOST_AUTO_TEST_CASE(TestInlierMatches) {
307+
BOOST_AUTO_TEST_CASE(TestTwoViewGeometry) {
308308
Database database(kMemoryDatabasePath);
309309
const image_t image_id1 = 1;
310310
const image_t image_id2 = 2;
@@ -326,10 +326,32 @@ BOOST_AUTO_TEST_CASE(TestInlierMatches) {
326326
BOOST_CHECK_EQUAL(two_view_geometry.inlier_matches[i].point2D_idx2,
327327
two_view_geometry_read.inlier_matches[i].point2D_idx2);
328328
}
329+
329330
BOOST_CHECK_EQUAL(two_view_geometry.config, two_view_geometry_read.config);
330331
BOOST_CHECK_EQUAL(two_view_geometry.F, two_view_geometry_read.F);
331332
BOOST_CHECK_EQUAL(two_view_geometry.E, two_view_geometry_read.E);
332333
BOOST_CHECK_EQUAL(two_view_geometry.H, two_view_geometry_read.H);
334+
335+
const TwoViewGeometry two_view_geometry_read_inv =
336+
database.ReadTwoViewGeometry(image_id2, image_id1);
337+
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.inlier_matches.size(),
338+
two_view_geometry_read.inlier_matches.size());
339+
for (size_t i = 0; i < two_view_geometry_read.inlier_matches.size(); ++i) {
340+
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.inlier_matches[i].point2D_idx2,
341+
two_view_geometry_read.inlier_matches[i].point2D_idx1);
342+
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.inlier_matches[i].point2D_idx1,
343+
two_view_geometry_read.inlier_matches[i].point2D_idx2);
344+
}
345+
346+
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.config,
347+
two_view_geometry_read.config);
348+
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.F.transpose(),
349+
two_view_geometry_read.F);
350+
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.E.transpose(),
351+
two_view_geometry_read.E);
352+
BOOST_CHECK(two_view_geometry_read_inv.H.inverse().eval().isApprox(
353+
two_view_geometry_read.H));
354+
333355
std::vector<image_pair_t> image_pair_ids;
334356
std::vector<TwoViewGeometry> two_view_geometries;
335357
database.ReadTwoViewGeometries(&image_pair_ids, &two_view_geometries);

src/feature/matching.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ void TransitiveFeatureMatcher::Run() {
13431343
std::vector<std::pair<image_t, image_t>> existing_image_pairs;
13441344
std::vector<int> existing_num_inliers;
13451345
database_.ReadTwoViewGeometryNumInliers(&existing_image_pairs,
1346-
&existing_num_inliers);
1346+
&existing_num_inliers);
13471347

13481348
CHECK_EQ(existing_image_pairs.size(), existing_num_inliers.size());
13491349

0 commit comments

Comments
 (0)