-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Color map optimization #230 #339
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.
Minor comment. Additional review is required.
return (u >= inner_margin && u < width_ - inner_margin && | ||
v >= inner_margin && v < height_ - inner_margin); | ||
} | ||
|
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 add this as it is frequently used in this PR. However, this function also can be in Geometry2D.h. Not quite sure this is the right place.
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 it is a good place.
return std::make_tuple(solution_exist, std::move(x)); | ||
if (check_det) { | ||
bool solution_exist = true; | ||
double det = A.determinant(); |
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 quite bad idea for large scale matrix. I add check_det
option here.
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.
Good.
@@ -53,7 +53,7 @@ Eigen::Vector6d TransformMatrix4dToVector6d(const Eigen::Matrix4d &input); | |||
|
|||
/// Function to solve Ax=b | |||
std::tuple<bool, Eigen::VectorXd> SolveLinearSystem( | |||
const Eigen::MatrixXd &A, const Eigen::VectorXd &b); | |||
const Eigen::MatrixXd &A, const Eigen::VectorXd &b, bool check_det = true); |
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.
it checkes determinant by default. Hence, it should not affect original pipeline.
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.
Good.
&TextureMapOptimization, | ||
"Function for optimizing texture mapping for reconstructed scenes", | ||
"mesh"_a, "imgs_rgbd"_a, "camera"_a, | ||
"option"_a = TextureMapOptmizationOption()); |
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 put texture_map_optimization in registration module. Not quite sure this is the right place.
I found a minor bug in this PR. Working on now. |
016ab36
to
4e5f37d
Compare
#include <Core/Geometry/RGBDImage.h> | ||
#include <Core/Geometry/TriangleMesh.h> | ||
#include <Core/Registration/ColorMapOptimization.h> | ||
#include <Core/Camera/PinholeCameraTrajectory.h> |
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.
Can we place ColorMapOptimization under py3d_registration? Can add these headers? Maybe this would not match the category.
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 color map optimization is a very good feature. We should highlight it. Registration is specifically about aligning point clouds. Color map optimization is more about putting color on a mesh. I think it is worth a separate folder. (At least it is at the same or larger scale of Integration or Odometry.)
sys.path.append("../Utility") | ||
from common import * | ||
|
||
path = "[set_this_path_to_fountain_dataset]" |
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 didn't include dataset for ColorMapOptimization. Instead, I had added google drive link to download the dataset. The file size for this tutorial is about 30MB (including mesh, 33 color and depth image pairs), which is not need to be maintained in Github repo.
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.
Good.
Wow, this is awesome! Let me review it during the weekend. |
4e5f37d
to
2110775
Compare
I have some non-trivial comments on this. So the review process is slow. |
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 amazing. My main issue is that we should move this out from Registration. Registration should be preserved for only 3d-to-3d alignment. RGB-D odometry is for RGB-D-to-RGB-D alignment, and color map optimization is kinda RGB-D-to-3D alignment. So it is totally worth a separate folder. Plus, this is a very useful function. In the future, we should also consider extend it with RGB-to-3D alignment.
Another minor comment is that we should also test on a sequence of a 360 scan. It is a pretty common use case, and can test if there is ghosting artifacts. See my detailed comments.
return (u >= inner_margin && u < width_ - inner_margin && | ||
v >= inner_margin && v < height_ - inner_margin); | ||
} | ||
|
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 it is a good place.
return std::make_tuple(solution_exist, std::move(x)); | ||
if (check_det) { | ||
bool solution_exist = true; | ||
double det = A.determinant(); |
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.
Good.
@@ -53,7 +53,7 @@ Eigen::Vector6d TransformMatrix4dToVector6d(const Eigen::Matrix4d &input); | |||
|
|||
/// Function to solve Ax=b | |||
std::tuple<bool, Eigen::VectorXd> SolveLinearSystem( | |||
const Eigen::MatrixXd &A, const Eigen::VectorXd &b); | |||
const Eigen::MatrixXd &A, const Eigen::VectorXd &b, bool check_det = true); |
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.
Good.
#include <Core/Geometry/RGBDImage.h> | ||
#include <Core/Geometry/TriangleMesh.h> | ||
#include <Core/Registration/ColorMapOptimization.h> | ||
#include <Core/Camera/PinholeCameraTrajectory.h> |
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 color map optimization is a very good feature. We should highlight it. Registration is specifically about aligning point clouds. Color map optimization is more about putting color on a mesh. I think it is worth a separate folder. (At least it is at the same or larger scale of Integration or Odometry.)
sys.path.append("../Utility") | ||
from common import * | ||
|
||
path = "[set_this_path_to_fountain_dataset]" |
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.
Good.
MakeVertexAndImageVisibility(const TriangleMesh& mesh, | ||
const std::vector<RGBDImage>& images_rgbd, | ||
const PinholeCameraTrajectory& camera, | ||
const ColorMapOptmizationOption& option) |
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 back when I made visibility test, I mask all vertices around depth discontinuity as invisible. This is because at depth discontinuity, the depth image becomes noisy, the measurement is not accurate in terms of both depth and x-y value. The projection also gets unstable. This happens frequently when you do a 360 scan of an object. So I chose to mask visible vertices only when:
- projected depth is close to the depth in depth image
- the point on depth image should have a normal close to the viewing ray
Can you try a sequence which is a 360 scan and see if you see any boundary ghosting? If so, the pixels around depth discontinuity need to be eroded.
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 also applies when averaging pixel values. Only points with a good normal orientation (not too far away from the viewing ray) gets averaged.
@syncle The build is broken. Can you check? |
cc44915
to
aa6c266
Compare
Got it. I am working on this now. This PR is also needed to be tested on the suggested case. |
549df4c
to
a0d0c05
Compare
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.
Self review on the revised version.
} | ||
} | ||
} | ||
} |
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 am not quite like this function. All the filtering functions in Open3D are implemented using 1D domain to save computational burden, but for this function, I had to use 4 nested for-loops. Maybe there would be better implementation for this.
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 it is fine for now. In the long run, we should seriously consider how to use OpenCV in Open3D. Actually I think vcpkg might be our savior. All that is missing is a package management system on Windows. Thus we had to include all the source code and are afraid of linking to big packages like OpenCV. But if Windows have a package management system, lots of our problems will be solved. We should invest time in this. @syncle @takanokage
"Function for color mapping of reconstructed scenes via optimization", | ||
"mesh"_a, "imgs_rgbd"_a, "camera"_a, | ||
"option"_a = ColorMapOptmizationOption()); | ||
} |
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 am not sure color map is good name for this module. We already uses color map name for vertex/mesh coloring. However, I had to use this name again because texture_map_optimization may lead users to think some 2D texture map representations.
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.
Yeah it is a bit confusing. But I can't come up with better names. Let's just use this one for now.
cnt += 1 | ||
copyfile(path + "/scene/cropped.ply", | ||
out_path + "/scene/integrated.ply") | ||
write_trajectory(traj, out_path + "scene/key.log") |
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 python script just samples every sampling_rate
frames from the RGBD sequence. Actually it would be good this script can select only sharp frames.
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.
Yes. This is a good point. A simple fix is to use cv2.Sobel
to generate the magnitude of image gradient, then sum it to estimate the sharpness. Then use a rolling window to pick the sharpest frames once in a while.
a0d0c05
to
0f61c65
Compare
Looks good. Merging. |
Is it normal for the Residual error increase in some iteration and decrease later?
[Iteration 0022] Residual error : 7256.626958, reg : 1210.944181 |
That may happen when images are being bended too much. You can notice |
Thank you very much. After the increase, the error decreased more stable. @syncle |
Consider turn off |
Do you have any plans to consider implementing alternating optimisation for Color map optimisation? |
I have commented that in #2686. |
Thanks, this information Is very useful. |
This resolves #230
Example:
![initial_zoom](https://user-images.githubusercontent.com/18297113/39620905-b421db56-4f41-11e8-9f88-8d55e157d874.png)
![non_rigid_zoom](https://user-images.githubusercontent.com/18297113/39620908-b45ded26-4f41-11e8-8ed4-90d3bb9fb5fb.png)