bdck commited on
Commit
ab4b137
·
verified ·
1 Parent(s): 99a77de

Upload depthpro_wrapper/io.py

Browse files
Files changed (1) hide show
  1. depthpro_wrapper/io.py +102 -0
depthpro_wrapper/io.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ I/O helpers for images and point-cloud files.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from pathlib import Path
8
+ from typing import Optional, Tuple, Union
9
+
10
+ import numpy as np
11
+ from PIL import Image
12
+
13
+
14
+ def load_image(path: Union[str, Path, Image.Image, np.ndarray]) -> Image.Image:
15
+ """
16
+ Normalise any image input to a PIL RGB image.
17
+
18
+ Parameters
19
+ ----------
20
+ path : str, Path, PIL.Image, or np.ndarray
21
+ If a string/Path, loaded from disk. If an ndarray, converted.
22
+
23
+ Returns
24
+ -------
25
+ PIL.Image.Image
26
+ RGB image ready for DepthPro.
27
+ """
28
+ if isinstance(path, (str, Path)):
29
+ return Image.open(str(path)).convert("RGB")
30
+ if isinstance(path, np.ndarray):
31
+ if path.dtype != np.uint8:
32
+ path = (path * 255).clip(0, 255).astype(np.uint8)
33
+ return Image.fromarray(path).convert("RGB")
34
+ if isinstance(path, Image.Image):
35
+ return path.convert("RGB")
36
+ raise TypeError(f"Unsupported image type: {type(path)}")
37
+
38
+
39
+ def save_point_cloud(
40
+ path: Union[str, Path],
41
+ points: np.ndarray,
42
+ colors: Optional[np.ndarray] = None,
43
+ normals: Optional[np.ndarray] = None,
44
+ ) -> None:
45
+ """
46
+ Save a point cloud to a PLY file.
47
+
48
+ Parameters
49
+ ----------
50
+ path : str or Path
51
+ Output file path. Should end with ``.ply``.
52
+ points : np.ndarray
53
+ (N, 3) float array of 3D positions.
54
+ colors : np.ndarray, optional
55
+ (N, 3) uint8 RGB colours.
56
+ normals : np.ndarray, optional
57
+ (N, 3) float array of normals.
58
+ """
59
+ path = Path(path)
60
+ points = np.asarray(points, dtype=np.float32)
61
+ has_colors = colors is not None
62
+ has_normals = normals is not None
63
+
64
+ header_lines = [
65
+ "ply",
66
+ "format ascii 1.0",
67
+ f"element vertex {len(points)}",
68
+ "property float x",
69
+ "property float y",
70
+ "property float z",
71
+ ]
72
+
73
+ if has_normals:
74
+ header_lines += [
75
+ "property float nx",
76
+ "property float ny",
77
+ "property float nz",
78
+ ]
79
+
80
+ if has_colors:
81
+ header_lines += [
82
+ "property uchar red",
83
+ "property uchar green",
84
+ "property uchar blue",
85
+ ]
86
+
87
+ header_lines += ["end_header"]
88
+
89
+ with open(path, "w") as f:
90
+ f.write("\n".join(header_lines) + "\n")
91
+ for i in range(len(points)):
92
+ row = [f"{points[i, 0]:.6f}", f"{points[i, 1]:.6f}", f"{points[i, 2]:.6f}"]
93
+ if has_normals:
94
+ row += [
95
+ f"{normals[i, 0]:.6f}",
96
+ f"{normals[i, 1]:.6f}",
97
+ f"{normals[i, 2]:.6f}",
98
+ ]
99
+ if has_colors:
100
+ c = np.clip(colors[i], 0, 255).astype(np.uint8)
101
+ row += [str(c[0]), str(c[1]), str(c[2])]
102
+ f.write(" ".join(row) + "\n")