Skip to content

Commit 78f58ca

Browse files
committed
WIP adding random object generation
1 parent 8af82d1 commit 78f58ca

File tree

3 files changed

+94
-9
lines changed

3 files changed

+94
-9
lines changed

smart_tree/data_types/cloud.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,21 @@ class LabelledCloud(Cloud):
9999
vector: torch.Tensor
100100
class_l: torch.Tensor
101101

102-
def __post_init__(self):
103-
num_classes = int(torch.max(self.class_l, 0)[0].item())
104-
self.cmap = torch.rand(num_classes + 1, 3)
102+
@property
103+
def number_classes(self):
104+
return int(torch.max(self.class_l, 0)[0].item()) + 1
105+
106+
@property
107+
def cmap(self):
108+
return torch.rand(self.number_classes, 3)
109+
110+
def __add__(self, other):
111+
xyz = torch.cat((self.xyz, other.xyz))
112+
rgb = torch.cat((self.rgb, other.rgb))
113+
vector = torch.cat((self.vector, other.vector))
114+
class_l = torch.cat((self.class_l, other.class_l))
115+
116+
return LabelledCloud(xyz, rgb, vector, class_l)
105117

106118
def filter(self, mask):
107119
return LabelledCloud(
@@ -196,5 +208,14 @@ def from_numpy(xyz, rgb, vector, class_l):
196208
torch.from_numpy(xyz).float(), # float64 -> these data types are stupid...
197209
torch.from_numpy(rgb).float(), # float64
198210
torch.from_numpy(vector).float(), # float32
199-
torch.from_numpy(class_l).float(), # int64
211+
torch.from_numpy(class_l).int(), # int64
212+
)
213+
214+
@staticmethod
215+
def from_o3d_cld(cld, class_l):
216+
return LabelledCloud.from_numpy(
217+
xyz=np.asarray(cld.points),
218+
rgb=np.asarray(cld.colors),
219+
vector=np.asarray(cld.points) * 0 - 1,
220+
class_l=np.asarray(class_l),
200221
)

smart_tree/dataset/augmentations.py

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
import numpy as np
44
import torch
5+
import random
6+
import open3d as o3d
57

8+
from pathlib import Path
69
from abc import ABC, abstractmethod
710
from typing import List
811

9-
from smart_tree.data_types.cloud import Cloud
12+
from smart_tree.data_types.cloud import Cloud, LabelledCloud
1013
from smart_tree.util.math.maths import euler_angles_to_rotation
14+
from smart_tree.util.file import load_o3d_mesh
1115
from hydra.utils import call, get_original_cwd, instantiate, to_absolute_path
1216

1317

@@ -73,6 +77,53 @@ def __call__(self, cloud):
7377
)
7478

7579

80+
class RandomMesh(Augmentation):
81+
def __init__(
82+
self,
83+
mesh_directory: Path,
84+
voxel_size: float,
85+
number_meshes: int,
86+
min_size: float,
87+
max_size: float,
88+
):
89+
self.mesh_paths = list(mesh_directory.glob("*"))
90+
self.voxel_size = voxel_size
91+
self.number_meshes = number_meshes
92+
self.min_size = min_size
93+
self.max_size = max_size
94+
self.class_number = 3
95+
96+
def __call__(self, cloud):
97+
for i in range(self.number_meshes):
98+
mesh = load_o3d_mesh(
99+
str(self.mesh_paths[random.randint(0, len(self.mesh_paths))])
100+
)
101+
102+
mesh = mesh.scale(0.01, center=mesh.get_center())
103+
104+
mesh = mesh.translate(-mesh.get_center())
105+
106+
mesh_pts = mesh.sample_points_uniformly(
107+
int(1000 * mesh.get_surface_area() / self.voxel_size),
108+
).paint_uniform_color(np.random.rand(3))
109+
110+
lc = LabelledCloud.from_o3d_cld(
111+
mesh_pts,
112+
class_l=torch.ones(np.asarray(mesh_pts.points).shape[0])
113+
* self.class_number,
114+
)
115+
116+
cloud += lc
117+
118+
# load random mesh
119+
# voxelize mesh
120+
# create labelled cloud
121+
# randomly translate / rotate it
122+
# return new cloud
123+
124+
return cloud
125+
126+
76127
class RandomDropout(Augmentation):
77128
def __init__(self, max_drop_out):
78129
self.max_drop_out = max_drop_out
@@ -127,13 +178,26 @@ def from_cfg(cfg):
127178

128179
if __name__ == "__main__":
129180
from pathlib import Path
130-
from smart_tree.util.file import load_cloud
181+
from smart_tree.util.file import load_data_npz
131182
from smart_tree.util.visualizer.view import o3d_viewer
132183

133-
cld = load_cloud(
134-
Path("/media/harry/harry's-data/PhD/training-data/apple/apple_1.npz")
184+
mesh_adder = RandomMesh(
185+
mesh_directory=Path("/local/Datasets/Thingi10K/raw_meshes/"),
186+
voxel_size=0.01,
187+
number_meshes=5,
188+
min_size=0.01,
189+
max_size=0.5,
135190
)
136191

192+
cld, _ = load_data_npz(Path("/local/_smart-tree/evaluation-data/gt/apple_12.npz"))
193+
194+
cld = mesh_adder(cld)
195+
196+
cld.view()
197+
198+
# o3d_viewer([cld])
199+
200+
quit()
137201
centre = CentreCloud()
138202
rotater = FixedRotate(torch.tensor([torch.pi / 2, torch.pi / 2, torch.pi * 2]))
139203
do = RandomDropout(0.5)

smart_tree/util/file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def load_o3d_lineset(path: Path):
154154

155155

156156
def load_o3d_mesh(path: Path):
157-
return o3d.io.read_triangle_model(path)
157+
return o3d.io.read_triangle_mesh(path)
158158

159159

160160
def save_skeleton(filename: Path, skeleton: TreeSkeleton):

0 commit comments

Comments
 (0)