14 #include <PinholeCameraTrajectoryIO.h>
19 #include "io/TriangleMeshIO.h"
37 const std::vector<double>& proxy_intensity,
41 const Eigen::Matrix4d& intrinsic,
42 const Eigen::Matrix4d& extrinsic,
43 const std::vector<int>& visibility_image_to_vertex,
44 const int image_boundary_margin) {
47 int vid = visibility_image_to_vertex[row];
49 Eigen::Vector4d g = extrinsic * Eigen::Vector4d(x(0), x(1), x(2), 1);
50 Eigen::Vector4d
uv = intrinsic * g;
51 double u =
uv(0) /
uv(2);
52 double v =
uv(1) /
uv(2);
55 double gray, dIdx, dIdy;
59 if (gray == -1.0)
return;
60 double invz = 1. / g(2);
61 double v0 = dIdx * intrinsic(0, 0) * invz;
62 double v1 = dIdy * intrinsic(1, 1) * invz;
63 double v2 = -(v0 * g(0) + v1 * g(1)) * invz;
64 J_r(0) = (-g(2) * v1 + g(1) * v2);
65 J_r(1) = (g(2) * v0 - g(0) * v2);
66 J_r(2) = (-g(1) * v0 + g(0) * v1);
70 r = (gray - proxy_intensity[vid]);
76 const std::vector<geometry::RGBDImage>& images_rgbd,
84 std::vector<geometry::Image> images_gray;
85 std::vector<geometry::Image> images_dx;
86 std::vector<geometry::Image> images_dy;
87 std::vector<geometry::Image> images_color;
88 std::vector<geometry::Image> images_depth;
89 std::vector<geometry::Image> images_mask;
90 std::vector<std::vector<int>> visibility_vertex_to_image;
91 std::vector<std::vector<int>> visibility_image_to_vertex;
96 std::vector<std::string> dirs{
101 for (
const std::string& dir : dirs) {
111 "Making directory failed: {}.", dir);
118 "[ColorMapOptimization] CreateUtilImagesFromRGBD");
119 std::tie(images_gray, images_dx, images_dy, images_color, images_depth) =
123 "[ColorMapOptimization] CreateDepthBoundaryMasks");
128 for (
size_t i = 0; i < images_mask.size(); ++i) {
137 "[ColorMapOptimization] CreateVertexAndImageVisibility");
138 std::tie(visibility_vertex_to_image, visibility_image_to_vertex) =
140 opt_mesh, images_depth, images_mask, opt_camera_trajectory,
145 std::vector<double> proxy_intensity;
147 int n_camera = int(opt_camera_trajectory.
parameters_.size());
150 opt_camera_trajectory, visibility_vertex_to_image, proxy_intensity,
154 double residual = 0.0;
156 #pragma omp parallel for schedule(static) \
157 num_threads(utility::EstimateMaxThreads())
158 for (
int c = 0; c < n_camera; c++) {
159 Eigen::Matrix4d pose;
160 pose = opt_camera_trajectory.
parameters_[c].extrinsic_;
162 auto intrinsic = opt_camera_trajectory.
parameters_[c]
163 .intrinsic_.intrinsic_matrix_;
164 auto extrinsic = opt_camera_trajectory.
parameters_[c].extrinsic_;
165 Eigen::Matrix4d intr = Eigen::Matrix4d::Zero();
166 intr.block<3, 3>(0, 0) = intrinsic;
173 i, J_r, r, w, opt_mesh, proxy_intensity, images_gray[c],
174 images_dx[c], images_dy[c], intr, extrinsic,
175 visibility_image_to_vertex[c],
181 std::tie(JTJ, JTr, r2) =
184 f_lambda, int(visibility_image_to_vertex[c].
size()),
188 Eigen::Matrix4d delta;
192 opt_camera_trajectory.
parameters_[c].extrinsic_ = pose;
193 #pragma omp critical(RunRigidOptimizer)
196 total_num_ += int(visibility_image_to_vertex[c].
size());
200 residual, residual / total_num_);
203 opt_camera_trajectory, visibility_vertex_to_image,
210 opt_camera_trajectory, visibility_vertex_to_image,
230 opt_camera_trajectory, visibility_vertex_to_image,
filament::Texture::InternalFormat format
Eigen::Vector3d getVertice(size_t index) const
std::vector< PinholeCameraParameters > parameters_
List of PinholeCameraParameters objects.
The Image class stores image with customizable width, height, num of channels and bytes per channel.
bool TestImageBoundary(double u, double v, double inner_margin=0.0) const
Test if coordinate (u, v) is located in the inner_marge of the image.
std::pair< bool, double > FloatValueAt(double u, double v) const
Eigen::Matrix< double, 6, 1 > Vector6d
Eigen::Matrix< double, 6, 6 > Matrix6d
Extending Eigen namespace by adding frequently used matrix type.
CLOUDVIEWER_HOST_DEVICE Pair< First, Second > make_pair(const First &_first, const Second &_second)
bool WriteTriangleMesh(const std::string &filename, const ccMesh &mesh, bool write_ascii, bool compressed, bool write_vertex_normals, bool write_vertex_colors, bool write_triangle_uvs, bool print_progress)
bool WriteImage(const std::string &filename, const geometry::Image &image, int quality=kCloudViewerImageIODefaultQuality)
bool WritePinholeCameraTrajectory(const std::string &filename, const camera::PinholeCameraTrajectory &trajectory)
void SetProxyIntensityForVertex(const ccMesh &mesh, const std::vector< geometry::Image > &images_gray, const utility::optional< std::vector< ImageWarpingField >> &warping_fields, const camera::PinholeCameraTrajectory &camera_trajectory, const std::vector< std::vector< int >> &visibility_vertex_to_image, std::vector< double > &proxy_intensity, int image_boundary_margin)
std::pair< ccMesh, camera::PinholeCameraTrajectory > RunRigidOptimizer(const ccMesh &mesh, const std::vector< geometry::RGBDImage > &images_rgbd, const camera::PinholeCameraTrajectory &camera_trajectory, const RigidOptimizerOption &option)
std::tuple< std::vector< std::vector< int > >, std::vector< std::vector< int > > > CreateVertexAndImageVisibility(const ccMesh &mesh, const std::vector< geometry::Image > &images_depth, const std::vector< geometry::Image > &images_mask, const camera::PinholeCameraTrajectory &camera_trajectory, double maximum_allowable_depth, double depth_threshold_for_visibility_check)
std::tuple< std::vector< geometry::Image >, std::vector< geometry::Image >, std::vector< geometry::Image >, std::vector< geometry::Image >, std::vector< geometry::Image > > CreateUtilImagesFromRGBD(const std::vector< geometry::RGBDImage > &images_rgbd)
std::vector< geometry::Image > CreateDepthBoundaryMasks(const std::vector< geometry::Image > &images_depth, double depth_threshold_for_discontinuity_check, int half_dilation_kernel_size_for_discontinuity_map)
void SetGeometryColorAverage(ccMesh &mesh, const std::vector< geometry::Image > &images_color, const utility::optional< std::vector< ImageWarpingField >> &warping_fields, const camera::PinholeCameraTrajectory &camera_trajectory, const std::vector< std::vector< int >> &visibility_vertex_to_image, int image_boundary_margin, int invisible_vertex_color_knn)
static void ComputeJacobianAndResidualRigid(int row, Eigen::Vector6d &J_r, double &r, double &w, const ccMesh &mesh, const std::vector< double > &proxy_intensity, const geometry::Image &images_gray, const geometry::Image &images_dx, const geometry::Image &images_dy, const Eigen::Matrix4d &intrinsic, const Eigen::Matrix4d &extrinsic, const std::vector< int > &visibility_image_to_vertex, const int image_boundary_margin)
bool MakeDirectoryHierarchy(const std::string &directory)
bool DirectoryExists(const std::string &directory)
std::tuple< bool, Eigen::Matrix4d > SolveJacobianSystemAndObtainExtrinsicMatrix(const Eigen::Matrix6d &JTJ, const Eigen::Vector6d &JTr)
constexpr nullopt_t nullopt
std::tuple< MatType, VecType, double > ComputeJTJandJTr(std::function< void(int, VecType &, double &, double &)> f, int iteration_num, bool verbose=true)
Generic file read and write utility for python interface.
int half_dilation_kernel_size_for_discontinuity_map_
double depth_threshold_for_visibility_check_
int image_boundary_margin_
int maximum_iteration_
Number of iterations for optimization steps.
double maximum_allowable_depth_
double depth_threshold_for_discontinuity_check_
int invisible_vertex_color_knn_
std::string debug_output_dir_