Skip to content

Commit

Permalink
Correctly invert two-view geometries when writing swapped image pair …
Browse files Browse the repository at this point in the history
…to database
  • Loading branch information
ahojnnes committed Jul 19, 2018
1 parent 885d239 commit 9f70659
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
32 changes: 19 additions & 13 deletions src/base/database.cc
Original file line number Diff line number Diff line change
Expand Up @@ -516,15 +516,15 @@ TwoViewGeometry Database::ReadTwoViewGeometry(const image_t image_id1,

SQLITE3_CALL(sqlite3_reset(sql_stmt_read_two_view_geometry_));

if (SwapImagePair(image_id1, image_id2)) {
SwapFeatureMatchesBlob(&blob);
}

two_view_geometry.inlier_matches = FeatureMatchesFromBlob(blob);
two_view_geometry.F.transposeInPlace();
two_view_geometry.E.transposeInPlace();
two_view_geometry.H.transposeInPlace();

if (SwapImagePair(image_id1, image_id2)) {
two_view_geometry.Invert();
}

return two_view_geometry;
}

Expand Down Expand Up @@ -695,26 +695,32 @@ void Database::WriteTwoViewGeometry(
SQLITE3_CALL(
sqlite3_bind_int64(sql_stmt_write_two_view_geometry_, 1, pair_id));

// Important: the swapped data must live until the query is executed.
FeatureMatchesBlob inlier_matches =
FeatureMatchesToBlob(two_view_geometry.inlier_matches);
const TwoViewGeometry* two_view_geometry_ptr = &two_view_geometry;

// Invert the two-view geometry if the image pair has to be swapped.
std::unique_ptr<TwoViewGeometry> swapped_two_view_geometry;
if (SwapImagePair(image_id1, image_id2)) {
SwapFeatureMatchesBlob(&inlier_matches);
swapped_two_view_geometry.reset(new TwoViewGeometry());
*swapped_two_view_geometry = two_view_geometry;
swapped_two_view_geometry->Invert();
two_view_geometry_ptr = swapped_two_view_geometry.get();
}

const FeatureMatchesBlob inlier_matches =
FeatureMatchesToBlob(two_view_geometry_ptr->inlier_matches);
WriteDynamicMatrixBlob(sql_stmt_write_two_view_geometry_, inlier_matches, 2);

SQLITE3_CALL(sqlite3_bind_int64(sql_stmt_write_two_view_geometry_, 5,
two_view_geometry.config));
two_view_geometry_ptr->config));

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

if (two_view_geometry.inlier_matches.size() > 0) {
if (two_view_geometry_ptr->inlier_matches.size() > 0) {
WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Ft, 6);
WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Et, 7);
WriteStaticMatrixBlob(sql_stmt_write_two_view_geometry_, Ht, 8);
Expand Down
24 changes: 23 additions & 1 deletion src/base/database_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ BOOST_AUTO_TEST_CASE(TestMatches) {
BOOST_CHECK_EQUAL(database.NumMatches(), 0);
}

BOOST_AUTO_TEST_CASE(TestInlierMatches) {
BOOST_AUTO_TEST_CASE(TestTwoViewGeometry) {
Database database(kMemoryDatabasePath);
const image_t image_id1 = 1;
const image_t image_id2 = 2;
Expand All @@ -326,10 +326,32 @@ BOOST_AUTO_TEST_CASE(TestInlierMatches) {
BOOST_CHECK_EQUAL(two_view_geometry.inlier_matches[i].point2D_idx2,
two_view_geometry_read.inlier_matches[i].point2D_idx2);
}

BOOST_CHECK_EQUAL(two_view_geometry.config, two_view_geometry_read.config);
BOOST_CHECK_EQUAL(two_view_geometry.F, two_view_geometry_read.F);
BOOST_CHECK_EQUAL(two_view_geometry.E, two_view_geometry_read.E);
BOOST_CHECK_EQUAL(two_view_geometry.H, two_view_geometry_read.H);

const TwoViewGeometry two_view_geometry_read_inv =
database.ReadTwoViewGeometry(image_id2, image_id1);
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.inlier_matches.size(),
two_view_geometry_read.inlier_matches.size());
for (size_t i = 0; i < two_view_geometry_read.inlier_matches.size(); ++i) {
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.inlier_matches[i].point2D_idx2,
two_view_geometry_read.inlier_matches[i].point2D_idx1);
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.inlier_matches[i].point2D_idx1,
two_view_geometry_read.inlier_matches[i].point2D_idx2);
}

BOOST_CHECK_EQUAL(two_view_geometry_read_inv.config,
two_view_geometry_read.config);
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.F.transpose(),
two_view_geometry_read.F);
BOOST_CHECK_EQUAL(two_view_geometry_read_inv.E.transpose(),
two_view_geometry_read.E);
BOOST_CHECK(two_view_geometry_read_inv.H.inverse().eval().isApprox(
two_view_geometry_read.H));

std::vector<image_pair_t> image_pair_ids;
std::vector<TwoViewGeometry> two_view_geometries;
database.ReadTwoViewGeometries(&image_pair_ids, &two_view_geometries);
Expand Down
2 changes: 1 addition & 1 deletion src/feature/matching.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@ void TransitiveFeatureMatcher::Run() {
std::vector<std::pair<image_t, image_t>> existing_image_pairs;
std::vector<int> existing_num_inliers;
database_.ReadTwoViewGeometryNumInliers(&existing_image_pairs,
&existing_num_inliers);
&existing_num_inliers);

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

Expand Down

0 comments on commit 9f70659

Please sign in to comment.