ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
class_io.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include <string>
9 #include <unordered_map>
10 
11 #include "pybind/docstring.h"
12 #include "pybind/t/io/io.h"
13 #include "t/geometry/PointCloud.h"
14 #include "t/io/ImageIO.h"
15 #include "t/io/NumpyIO.h"
16 #include "t/io/PointCloudIO.h"
17 #include "t/io/TriangleMeshIO.h"
18 
19 namespace cloudViewer {
20 namespace t {
21 namespace io {
22 
23 // IO functions have similar arguments, thus the arg docstrings may be shared
24 static const std::unordered_map<std::string, std::string>
26  {"filename", "Path to file."},
27  // Write options
28  {"compressed",
29  "Set to ``True`` to write in compressed format."},
30  {"format",
31  "The format of the input file. When not specified or set as "
32  "``auto``, the format is inferred from file extension name."},
33  {"remove_nan_points",
34  "If true, all points that include a NaN are removed from "
35  "the PointCloud."},
36  {"remove_infinite_points",
37  "If true, all points that include an infinite value are "
38  "removed from the PointCloud."},
39  {"quality", "Quality of the output file."},
40  {"write_ascii",
41  "Set to ``True`` to output in ascii format, otherwise binary "
42  "format will be used."},
43  {"write_vertex_normals",
44  "Set to ``False`` to not write any vertex normals, even if "
45  "present on the mesh."},
46  {"write_vertex_colors",
47  "Set to ``False`` to not write any vertex colors, even if "
48  "present on the mesh."},
49  {"write_triangle_uvs",
50  "Set to ``False`` to not write any triangle uvs, even if "
51  "present on the mesh. For ``obj`` format, mtl file is saved "
52  "only when ``True`` is set."},
53  // Entities
54  {"config", "AzureKinectSensor's config file."},
55  {"pointcloud", "The ``PointCloud`` object for I/O."},
56  {"mesh", "The ``TriangleMesh`` object for I/O."},
57  {"line_set", "The ``LineSet`` object for I/O."},
58  {"image", "The ``Image`` object for I/O."},
59  {"voxel_grid", "The ``VoxelGrid`` object for I/O."},
60  {"trajectory",
61  "The ``PinholeCameraTrajectory`` object for I/O."},
62  {"intrinsic", "The ``PinholeCameraIntrinsic`` object for I/O."},
63  {"parameters",
64  "The ``PinholeCameraParameters`` object for I/O."},
65  {"pose_graph", "The ``PoseGraph`` object for I/O."},
66  {"feature", "The ``Feature`` object for I/O."},
67  {"print_progress",
68  "If set to true a progress bar is visualized in the console."},
69 };
70 
71 void pybind_class_io(py::module &m_io) {
72  // cloudViewer::t::geometry::Image
73  m_io.def(
74  "read_image",
75  [](const fs::path &filename) {
76  py::gil_scoped_release release;
78  ReadImage(filename.string(), image);
79  return image;
80  },
81  "Function to read image from file.", "filename"_a);
82  docstring::FunctionDocInject(m_io, "read_image",
84 
85  m_io.def(
86  "write_image",
87  [](const fs::path &filename, const geometry::Image &image,
88  int quality) {
89  py::gil_scoped_release release;
90  return WriteImage(filename.string(), image, quality);
91  },
92  "Function to write Image to file.", "filename"_a, "image"_a,
93  "quality"_a = kCloudViewerImageIODefaultQuality);
94  docstring::FunctionDocInject(m_io, "write_image",
96 
97  // cloudViewer::t::geometry::PointCloud
98  m_io.def(
99  "read_point_cloud",
100  [](const fs::path &filename, const std::string &format,
101  bool remove_nan_points, bool remove_infinite_points,
102  bool print_progress) {
103  py::gil_scoped_release release;
105  ReadPointCloud(filename.string(), pcd,
106  {format, remove_nan_points,
107  remove_infinite_points, print_progress});
108  return pcd;
109  },
110  "Function to read PointCloud with tensor attributes from file.",
111  "filename"_a, "format"_a = "auto", "remove_nan_points"_a = false,
112  "remove_infinite_points"_a = false, "print_progress"_a = false);
113  docstring::FunctionDocInject(m_io, "read_point_cloud",
115 
116  m_io.def(
117  "write_point_cloud",
118  [](const fs::path &filename,
119  const t::geometry::PointCloud &pointcloud, bool write_ascii,
120  bool compressed, bool print_progress) {
121  py::gil_scoped_release release;
122  return WritePointCloud(
123  filename.string(), pointcloud,
124  {write_ascii, compressed, print_progress});
125  },
126  "Function to write PointCloud with tensor attributes to file.",
127  "filename"_a, "pointcloud"_a, "write_ascii"_a = false,
128  "compressed"_a = false, "print_progress"_a = false);
129  docstring::FunctionDocInject(m_io, "write_point_cloud",
131 
132  // ccMesh
133  m_io.def(
134  "read_triangle_mesh",
135  [](const fs::path &filename, bool enable_post_processing,
136  bool print_progress) {
137  py::gil_scoped_release release;
140  opt.enable_post_processing = enable_post_processing;
141  opt.print_progress = print_progress;
142  ReadTriangleMesh(filename.string(), mesh, opt);
143  return mesh;
144  },
145  "Function to read TriangleMesh from file", "filename"_a,
146  "enable_post_processing"_a = false, "print_progress"_a = false,
147  R"doc(The general entrance for reading a TriangleMesh from a file.
148 The function calls read functions based on the extension name of filename.
149 Supported formats are `obj, ply, stl, off, gltf, glb, fbx`.
150 
151 The following example reads a triangle mesh with the .ply extension::
152 import cloudViewer as cv3d
153 mesh = cv3d.t.io.read_triangle_mesh('mesh.ply')
154 
155 Args:
156 filename (str): Path to the mesh file.
157 enable_post_processing (bool): If True enables post-processing.
158  Post-processing will
159  - triangulate meshes with polygonal faces
160  - remove redundant materials
161  - pretransform vertices
162  - generate face normals if needed
163 
164  For more information see ASSIMPs documentation on the flags
165  `aiProcessPreset_TargetRealtime_Fast, aiProcess_RemoveRedundantMaterials,
166  aiProcess_OptimizeMeshes, aiProcess_PreTransformVertices`.
167 
168  Note that identical vertices will always be joined regardless of whether
169  post-processing is enabled or not, which changes the number of vertices
170  in the mesh.
171 
172  The `ply`-format is not affected by the post-processing.
173 
174 print_progress (bool): If True print the reading progress to the terminal.
175 
176 Returns:
177 Returns the mesh object. On failure an empty mesh is returned.
178 )doc");
179 
180  m_io.def(
181  "write_triangle_mesh",
182  [](const fs::path &filename, const t::geometry::TriangleMesh &mesh,
183  bool write_ascii, bool compressed, bool write_vertex_normals,
184  bool write_vertex_colors, bool write_triangle_uvs,
185  bool print_progress) {
186  py::gil_scoped_release release;
187  return WriteTriangleMesh(filename.string(), mesh, write_ascii,
188  compressed, write_vertex_normals,
189  write_vertex_colors,
190  write_triangle_uvs, print_progress);
191  },
192  "Function to write TriangleMesh to file", "filename"_a, "mesh"_a,
193  "write_ascii"_a = false, "compressed"_a = false,
194  "write_vertex_normals"_a = true, "write_vertex_colors"_a = true,
195  "write_triangle_uvs"_a = true, "print_progress"_a = false);
196  docstring::FunctionDocInject(m_io, "write_triangle_mesh",
198 
199  // ---- Numpy IO ----
200  m_io.def(
201  "read_numpy",
202  [](const std::string &filename) {
203  py::gil_scoped_release release;
204  return ReadNpy(filename);
205  },
206  "Read a numpy .npy file into a Tensor.", "filename"_a);
207  docstring::FunctionDocInject(m_io, "read_numpy",
209 
210  m_io.def(
211  "write_numpy",
212  [](const std::string &filename, const core::Tensor &tensor) {
213  py::gil_scoped_release release;
214  WriteNpy(filename, tensor);
215  },
216  "Write a Tensor to a numpy .npy file.", "filename"_a, "tensor"_a);
217  docstring::FunctionDocInject(m_io, "write_numpy",
219 
220  m_io.def(
221  "read_npz",
222  [](const std::string &filename) {
223  py::gil_scoped_release release;
224  return ReadNpz(filename);
225  },
226  "Read a numpy .npz file into a dict[str, Tensor].", "filename"_a);
227  docstring::FunctionDocInject(m_io, "read_npz",
229 
230  m_io.def(
231  "write_npz",
232  [](const std::string &filename,
233  const std::unordered_map<std::string, core::Tensor>
234  &tensor_map) {
235  py::gil_scoped_release release;
236  WriteNpz(filename, tensor_map);
237  },
238  "Write a dict[str, Tensor] to a numpy .npz file.", "filename"_a,
239  "tensor_map"_a);
240  docstring::FunctionDocInject(m_io, "write_npz",
242 
243  // DepthNoiseSimulator
244  py::class_<DepthNoiseSimulator> depth_noise_simulator(
245  m_io, "DepthNoiseSimulator",
246  R"(Simulate depth image noise from a given noise distortion model. The distortion model is based on *Teichman et. al. "Unsupervised intrinsic calibration of depth sensors via SLAM" RSS 2009*. Also see <http://redwood-data.org/indoor/dataset.html>__
247 
248 Example::
249 
250  import cloudViewer as cv3d
251 
252  # Redwood Indoor LivingRoom1 (Augmented ICL-NUIM)
253  # http://redwood-data.org/indoor/
254  data = cv3d.data.RedwoodIndoorLivingRoom1()
255  noise_model_path = data.noise_model_path
256  im_src_path = data.depth_paths[0]
257  depth_scale = 1000.0
258 
259  # Read clean depth image (uint16)
260  im_src = cv3d.t.io.read_image(im_src_path)
261 
262  # Run noise model simulation
263  simulator = cv3d.t.io.DepthNoiseSimulator(noise_model_path)
264  im_dst = simulator.simulate(im_src, depth_scale=depth_scale)
265 
266  # Save noisy depth image (uint16)
267  cv3d.t.io.write_image("noisy_depth.png", im_dst)
268  )");
269  depth_noise_simulator.def(py::init([](const fs::path &fielname) {
270  return DepthNoiseSimulator(fielname.string());
271  }),
272  "noise_model_path"_a);
273  depth_noise_simulator.def("simulate", &DepthNoiseSimulator::Simulate,
274  "im_src"_a, "depth_scale"_a = 1000.0f,
275  "Apply noise model to a depth image.");
276  depth_noise_simulator.def(
277  "enable_deterministic_debug_mode",
279  "Enable deterministic debug mode. All normally distributed noise "
280  "will be replaced by 0.");
281  depth_noise_simulator.def_property_readonly(
282  "noise_model", &DepthNoiseSimulator::GetNoiseModel,
283  "The noise model tensor.");
285  m_io, "DepthNoiseSimulator", "__init__",
286  {{"noise_model_path",
287  "Path to the noise model file. See "
288  "http://redwood-data.org/indoor/dataset.html for the format. Or, "
289  "you may use one of our example datasets, e.g., "
290  "RedwoodIndoorLivingRoom1."}});
292  m_io, "DepthNoiseSimulator", "simulate",
293  {{"im_src",
294  "Source depth image, must be with dtype UInt16 or Float32, "
295  "channels==1."},
296  {"depth_scale",
297  "Scale factor to the depth image. As a sanity check, if the "
298  "dtype is Float32, the depth_scale must be 1.0. If the dtype is "
299  "is UInt16, the depth_scale is typically larger than 1.0, e.g. "
300  "it can be 1000.0."}});
301  docstring::ClassMethodDocInject(m_io, "DepthNoiseSimulator",
302  "enable_deterministic_debug_mode");
303 }
304 
305 } // namespace io
306 } // namespace t
307 } // namespace cloudViewer
IsAscii write_ascii
Compressed compressed
std::string filename
std::shared_ptr< core::Tensor > image
filament::Texture::InternalFormat format
The Image class stores image with customizable rows, cols, channels, dtype and device.
Definition: Image.h:29
A point cloud contains a list of 3D points.
Definition: PointCloud.h:82
A triangle mesh contains vertices and triangles.
Definition: TriangleMesh.h:98
void EnableDeterministicDebugMode()
Enable deterministic debug mode. All normally distributed noise will be replaced by 0.
Definition: ImageIO.h:104
core::Tensor GetNoiseModel() const
Return the noise model.
Definition: ImageIO.h:100
geometry::Image Simulate(const geometry::Image &im_src, float depth_scale=1000.0)
Apply noise model to a depth image.
Definition: ImageIO.cpp:158
void ClassMethodDocInject(py::module &pybind_module, const std::string &class_name, const std::string &function_name, const std::unordered_map< std::string, std::string > &map_parameter_body_docs)
Definition: docstring.cpp:27
void FunctionDocInject(py::module &pybind_module, const std::string &function_name, const std::unordered_map< std::string, std::string > &map_parameter_body_docs)
Definition: docstring.cpp:76
static const std::string path
Definition: PointCloud.cpp:59
bool ReadTriangleMesh(const std::string &filename, geometry::TriangleMesh &mesh, cloudViewer::io::ReadTriangleMeshOptions params)
std::unordered_map< std::string, core::Tensor > ReadNpz(const std::string &file_name)
Definition: NumpyIO.cpp:675
bool WritePointCloud(const std::string &filename, const geometry::PointCloud &pointcloud, const cloudViewer::io::WritePointCloudOption &params)
constexpr int kCloudViewerImageIODefaultQuality
Definition: ImageIO.h:33
core::Tensor ReadNpy(const std::string &file_name)
Definition: NumpyIO.cpp:662
bool ReadImage(const std::string &filename, geometry::Image &image)
Definition: ImageIO.cpp:55
void WriteNpz(const std::string &file_name, const std::unordered_map< std::string, core::Tensor > &tensor_map)
Definition: NumpyIO.cpp:759
static const std::unordered_map< std::string, std::string > map_shared_argument_docstrings
Definition: class_io.cpp:25
bool ReadPointCloud(const std::string &filename, geometry::PointCloud &pointcloud, const cloudViewer::io::ReadPointCloudOption &params)
void pybind_class_io(py::module &m_io)
Definition: class_io.cpp:71
bool WriteImage(const std::string &filename, const geometry::Image &image, int quality)
Definition: ImageIO.cpp:79
bool WriteTriangleMesh(const std::string &filename, const geometry::TriangleMesh &mesh, bool write_ascii, bool compressed, bool write_vertex_normals, bool write_vertex_colors, bool write_triangle_uvs, bool print_progress)
void WriteNpy(const std::string &file_name, const core::Tensor &tensor)
Definition: NumpyIO.cpp:671
Generic file read and write utility for python interface.
bool enable_post_processing
Enables post-processing on the mesh.
Definition: AutoIO.h:26