|
2 | 2 |
|
3 | 3 | import numpy as np |
4 | 4 | import torch |
| 5 | +import random |
| 6 | +import open3d as o3d |
5 | 7 |
|
| 8 | +from pathlib import Path |
6 | 9 | from abc import ABC, abstractmethod |
7 | 10 | from typing import List |
8 | 11 |
|
9 | | -from smart_tree.data_types.cloud import Cloud |
| 12 | +from smart_tree.data_types.cloud import Cloud, LabelledCloud |
10 | 13 | from smart_tree.util.math.maths import euler_angles_to_rotation |
| 14 | +from smart_tree.util.file import load_o3d_mesh |
11 | 15 | from hydra.utils import call, get_original_cwd, instantiate, to_absolute_path |
12 | 16 |
|
13 | 17 |
|
@@ -73,6 +77,53 @@ def __call__(self, cloud): |
73 | 77 | ) |
74 | 78 |
|
75 | 79 |
|
| 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 | + |
76 | 127 | class RandomDropout(Augmentation): |
77 | 128 | def __init__(self, max_drop_out): |
78 | 129 | self.max_drop_out = max_drop_out |
@@ -127,13 +178,26 @@ def from_cfg(cfg): |
127 | 178 |
|
128 | 179 | if __name__ == "__main__": |
129 | 180 | from pathlib import Path |
130 | | - from smart_tree.util.file import load_cloud |
| 181 | + from smart_tree.util.file import load_data_npz |
131 | 182 | from smart_tree.util.visualizer.view import o3d_viewer |
132 | 183 |
|
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, |
135 | 190 | ) |
136 | 191 |
|
| 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() |
137 | 201 | centre = CentreCloud() |
138 | 202 | rotater = FixedRotate(torch.tensor([torch.pi / 2, torch.pi / 2, torch.pi * 2])) |
139 | 203 | do = RandomDropout(0.5) |
|
0 commit comments