Revisiting #1504 and fix colmap world coordinate transform #2793
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Okay, I spent some time to research how we maintain world coordinate conventions between colmap and nerfstudio, and I found the current implementation is not correct (original introduced in a very earlier commit #338 ). Let me first describe my understanding, then what the existing code does and finally what should be the fix. This fix addresses a historic issue: #1504
The Problem
Given a c2w transform read from colmap, we need apply two transforms, one multiplied from right, one multiplied from left.
Ideally, the code should look like
Here
Now, let's look at the existing code
Here as implemented in the current code:
However, the second step was not correctly implemented. Because in Colmapworld coordinate convention, the y direction is often interpreted as DOWN direction. This is because the bundle adjustment optimization often starts from using the first opencv camera frame as world frame. Assuming the optimization hasn't deviate the first frame's pose a lot, the y direction in colmap world would be close to DOWN direction.
In order to transform the world convention from colmap to nerfstudio, the correct B should be
where we map (-y) in colmap world to z in nerfstudio world. And the code should be corrected effectively as
Later in nerfstudio commit history, we introduce new feature
--orientation_method
in colmap parser, and the choice of B becomes irrelevant if theorientation_method
is notnone
. The viewer will always display correct orientation as long as the orientation_method is not none. So in order to test my fix, I run ns-train withns-train gaussian-splatting ... colmap --orientation_method=none
and open up my viewer to verify the initial world coordinate setup. See pictures below on mipnerf360 bicycle dataset:Without fix

With fix
Summary of this change
orientation_method
is notnone
(by default it is set toup
), the change of this PR has no material impact on outcomes of train (e.g. checkpoint, ply exporter) or viewer. The scene will be oriented as instructed by the parameter. For regular user, whom never touch this parameter other than the default setting, this PR has no impacts for them.orientation_method
isnone
, this is a case we want to properly transform the world coordinate of colmap project to nerfstudio convention.assume_colmap_world_coordinate_convention
): Iforientation_method
is none, andassume_colmap_world_coordinate_convention
is False (by default it is true), we will not apply B transform at all.Why we need this change?
Users may want to orient the scene using some prior knowledge instead of using what is provided by the nerfstudio, therefore we need effect 1. User may want to orient the scene using nerfstudio world convention instead of colmap convention, then we need effect 2.
Other related issues that can find answer in this PR:
#2784