Skip to content
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

Adding expressive GTSFM data to allow non-consecutive cameras #113

Merged
merged 31 commits into from
Mar 25, 2021

Conversation

ayushbaid
Copy link
Contributor

The current SfmData structure stores the camera as a list, and hence needs all the image to have a valid camera. This is not the case when some upstream module drops cameras.

The new data structure uses a dictionary to store the cameras, and hence can store non-contiguous cameras.

@ayushbaid
Copy link
Contributor Author

Some changes in the PR are just fixing the unit tests failing due to #104.

gtsfm/utils/io.py Outdated Show resolved Hide resolved
gtsfm/utils/io.py Outdated Show resolved Hide resolved
gtsfm/utils/io.py Outdated Show resolved Hide resolved
gtsfm/utils/io.py Outdated Show resolved Hide resolved
gtsfm/utils/io.py Outdated Show resolved Hide resolved
gtsfm/utils/io.py Outdated Show resolved Hide resolved
"""

# TODO: get image shape somehow

Copy link
Collaborator

@johnwlambert johnwlambert Mar 23, 2021

Choose a reason for hiding this comment

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

i believe to match COLMAP, we need also to dump 4 lines:

f.write("# Image list with two lines of data per image:\n")
f.write("#   IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME\n")
f.write("#   POINTS2D[] as (X, Y, POINT3D_ID)\n")
f.write(f"# Number of images: {num_imgs}, mean observations per image: {mean_obs_per_img}")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can I make a different PR to match the format of COLMAP? I feel it will make it easier to land?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sure.

@@ -213,12 +211,20 @@ def create_computation_graph(
if self._save_bal_files:
# save the input to Bundle Adjustment (from data association)
auxiliary_graph_list.append(
dask.delayed(write_sfmdata_to_disk)(ba_input_graph, os.path.join(RESULTS_PATH, "ba_input.bal"))
dask.delayed(io_utils.write_cameras)(ba_input_graph, os.path.join(RESULTS_PATH, "ba_input_cameras.txt"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

i see why you named these differently, because we have multiple versions, and we want to differentiate between them.

But can we just put them in separate subdirectories? Per https://colmap.github.io/cli.html, we need to preserve the names to be compatible:

COLMAP as far as I know
Screen Shot 2021-03-22 at 10 42 53 PM

dask.delayed(io_utils.write_cameras)(ba_input_graph, os.path.join(RESULTS_PATH, "ba_input_cameras.txt"))
)
auxiliary_graph_list.append(
dask.delayed(io_utils.write_images)(ba_input_graph, os.path.join(RESULTS_PATH, "ba_input_images.txt"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we save "points3D.txt" as well here?

gtsfm/utils/io.py Outdated Show resolved Hide resolved
self.assertEqual(computed.get_camera(2), computed.get_camera(2))
self.assertEqual(computed.number_tracks(), 0)

@mock.patch.object(graph_utils, "get_nodes_in_largest_connected_component", return_value=[1, 2, 4])
Copy link
Collaborator

Choose a reason for hiding this comment

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

do you mind adding an inline comment explaining why we need to use mock here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

better?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not too familiar with the mocking lib in Python or when we need it -- could you explain a little more about why a typical function call won't work?

return GtsfmData.pick_cameras(self, cameras_in_largest_cc)

@classmethod
def pick_cameras(cls, gtsfm_data: "GtsfmData", camera_indices: List[int]) -> "GtsfmData":
Copy link
Collaborator

Choose a reason for hiding this comment

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

looks great @ayushbaid . much better. only thing i might change is to name this
def from_picked_cameras()

I think class methods often start with from_blah to make their factory functionality clearer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

@johnwlambert johnwlambert merged commit e9654ae into master Mar 25, 2021
@johnwlambert
Copy link
Collaborator

Thanks @ayushbaid !

@johnwlambert johnwlambert deleted the feature/gtsam-data branch March 25, 2021 20:17
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.

None yet

2 participants