forked from antimatter15/splat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
convert.py
78 lines (68 loc) · 2.4 KB
/
convert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# You can use this to convert a .ply file to a .splat file programmatically in python
# Alternatively you can drag and drop a .ply file into the viewer at https://antimatter15.com/splat
from plyfile import PlyData
import numpy as np
import argparse
from io import BytesIO
def process_ply_to_splat(ply_file_path):
plydata = PlyData.read(ply_file_path)
vert = plydata["vertex"]
sorted_indices = np.argsort(
-np.exp(vert["scale_0"] + vert["scale_1"] + vert["scale_2"])
/ (1 + np.exp(-vert["opacity"]))
)
buffer = BytesIO()
for idx in sorted_indices:
v = plydata["vertex"][idx]
position = np.array([v["x"], v["y"], v["z"]], dtype=np.float32)
scales = np.exp(
np.array(
[v["scale_0"], v["scale_1"], v["scale_2"]],
dtype=np.float32,
)
)
rot = np.array(
[v["rot_0"], v["rot_1"], v["rot_2"], v["rot_3"]],
dtype=np.float32,
)
SH_C0 = 0.28209479177387814
color = np.array(
[
0.5 + SH_C0 * v["f_dc_0"],
0.5 + SH_C0 * v["f_dc_1"],
0.5 + SH_C0 * v["f_dc_2"],
1 / (1 + np.exp(-v["opacity"])),
]
)
buffer.write(position.tobytes())
buffer.write(scales.tobytes())
buffer.write((color * 255).clip(0, 255).astype(np.uint8).tobytes())
buffer.write(
((rot / np.linalg.norm(rot)) * 128 + 128)
.clip(0, 255)
.astype(np.uint8)
.tobytes()
)
return buffer.getvalue()
def save_splat_file(splat_data, output_path):
with open(output_path, "wb") as f:
f.write(splat_data)
def main():
parser = argparse.ArgumentParser(description="Convert PLY files to SPLAT format.")
parser.add_argument(
"input_files", nargs="+", help="The input PLY files to process."
)
parser.add_argument(
"--output", "-o", default="output.splat", help="The output SPLAT file."
)
args = parser.parse_args()
for input_file in args.input_files:
print(f"Processing {input_file}...")
splat_data = process_ply_to_splat(input_file)
output_file = (
args.output if len(args.input_files) == 1 else input_file + ".splat"
)
save_splat_file(splat_data, output_file)
print(f"Saved {output_file}")
if __name__ == "__main__":
main()