Skip to content

Initialize shonan using minimum spanning tree#777

Open
ayushbaid wants to merge 28 commits intomasterfrom
feature/shonan_mst_init
Open

Initialize shonan using minimum spanning tree#777
ayushbaid wants to merge 28 commits intomasterfrom
feature/shonan_mst_init

Conversation

@ayushbaid
Copy link
Copy Markdown
Contributor

No description provided.

Comment thread gtsfm/averaging/rotation/shonan.py Outdated
@ayushbaid
Copy link
Copy Markdown
Contributor Author

I cannot make sense of the results. For datasets where GTSFM performs poorly, we do good. However, we see some regression on other datasets.

rotation_avergaging_result

ba_result

Comment thread gtsfm/averaging/rotation/shonan.py Outdated
Comment thread gtsfm/utils/rotation.py Outdated
Comment thread gtsfm/utils/rotation.py Outdated
Comment thread gtsfm/utils/rotation.py Outdated
Comment thread gtsfm/utils/rotation.py
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would spanning_tree be a better name for this file?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I indented to keep all rotations related util functions here. I feel this is not as generic to be named a spanning tree right now because the args are rotations and not a generic type.

@johnwlambert
Copy link
Copy Markdown
Collaborator

@ayushbaid CI appears to still be failing:

=========================== short test summary info ============================
FAILED tests/averaging/rotation/test_shonan.py::TestShonanRotationAveraging::test_circle_all_edges - AssertionError: False is not true
====== 1 failed, 435 passed, 7 skipped, 21 warnings in 982.10s (0:16:22) =======
Error: Process completed with exit code 1.

Comment thread gtsfm/utils/rotation.py Outdated
Comment thread gtsfm/utils/rotation.py Outdated
Comment thread gtsfm/utils/rotation.py Outdated
Comment thread gtsfm/utils/rotation.py Outdated
from gtsam import Rot3


def random_rotation() -> Rot3:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ayushbaid appears to be unused, right?

Comment thread tests/utils/test_rotation_utils.py Outdated

class TestRotationUtil(unittest.TestCase):
def test_mst_initialization(self):
"""Test for 4 poses in a circle, with a pose connected all others."""
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: typo "connected to all others"?

Comment thread gtsfm/utils/rotation.py Outdated
# Compute the Minimum Spanning Tree (MST)
mst = nx.minimum_spanning_tree(graph)

wRis = [Rot3() for _ in range(num_images)]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code will only work if the poses are given in an ordered line

wRi_list_euler_deg_est = [np.rad2deg(wRi.roll()) for wRi in wRi_list_computed]
assert np.allclose(wRi_list_euler_deg_est, wRi_list_euler_deg_expected)

def test_greedily_construct_st_mixed_order_chain(self) -> None:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ayushbaid I added a test that fails with the current implementation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to change the lookup logic? Or do you have a fix in mind?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a fix -- traversing the shortest path in the MST between the origin and destination, and chaining the poses together

Comment thread gtsfm/utils/rotation.py Outdated



def initialize_mst(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ayushbaid maybe we should consider Travis' implementation here?

Comment thread gtsfm/utils/rotation.py
Comment on lines +54 to +57
if i1 < i2:
i1Ri2 = i2Ri1_dict[(i1, i2)].inverse()
else:
i1Ri2 = i2Ri1_dict[(i2, i1)]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not guaranteed, right?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm why not?

Copy link
Copy Markdown
Collaborator

@akshay-krishnan akshay-krishnan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High level comments:

  • I think a better API to is pass "edge_weights" to the averaging modules, not the correspondences. The edge weights can be computed in the verifier for instance. Not a blocker for this PR though.

  • I think this initialization should be made optional, with a flag to change it. This would be a blocker for me :)

Comment thread gtsfm/utils/rotation.py Outdated
return wRi_list


# def initialize_mst(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this not used? if not, please remove.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread tests/averaging/rotation/test_shonan.py Outdated
"""
i1Ti2_priors: Dict[Tuple[int, int], PosePrior] = {}
wRi_computed = self.obj.run_rotation_averaging(len(wRi_expected), i2Ri1_input, i1Ti2_priors)
two_view_estimation_reports = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add another test, keeping this one unchanged, (for default behavior that does not need two view reports)?

Comment thread tests/averaging/rotation/test_shonan.py Outdated
self.assertTrue(
geometry_comparisons.compare_rotations(wRi_computed, expected_wRi_list, ROTATION_ANGLE_ERROR_THRESHOLD_DEG)
)
# def test_simple_with_prior(self):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this being removed?

@ayushbaid ayushbaid force-pushed the feature/shonan_mst_init branch from 3a1cfd5 to 429177a Compare May 13, 2024 05:24
relative_rotations_angles = np.array(
[compute_relative_rotation_angle(aRi, aRi_) for (aRi, aRi_) in zip(aRi_list, aRi_list_)], dtype=np.float32
)
print(relative_rotations_angles)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be removed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants