-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initialize shonan using minimum spanning tree #777
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
@ayushbaid CI appears to still be failing:
|
gtsfm/utils/rotation.py
Outdated
from gtsam import Rot3 | ||
|
||
|
||
def random_rotation() -> Rot3: |
There was a problem hiding this comment.
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?
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.""" |
There was a problem hiding this comment.
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"?
gtsfm/utils/rotation.py
Outdated
# Compute the Minimum Spanning Tree (MST) | ||
mst = nx.minimum_spanning_tree(graph) | ||
|
||
wRis = [Rot3() for _ in range(num_images)] |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
gtsfm/utils/rotation.py
Outdated
|
||
|
||
|
||
def initialize_mst( |
There was a problem hiding this comment.
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?
if i1 < i2: | ||
i1Ri2 = i2Ri1_dict[(i1, i2)].inverse() | ||
else: | ||
i1Ri2 = i2Ri1_dict[(i2, i1)] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm why not?
There was a problem hiding this 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 :)
gtsfm/utils/rotation.py
Outdated
return wRi_list | ||
|
||
|
||
# def initialize_mst( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
""" | ||
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 = { |
There was a problem hiding this comment.
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)?
self.assertTrue( | ||
geometry_comparisons.compare_rotations(wRi_computed, expected_wRi_list, ROTATION_ANGLE_ERROR_THRESHOLD_DEG) | ||
) | ||
# def test_simple_with_prior(self): |
There was a problem hiding this comment.
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?
3a1cfd5
to
429177a
Compare
@@ -55,6 +56,7 @@ def compare_rotations( | |||
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to be removed
No description provided.