|
15 | 15 | - CV
|
16 | 16 | - DATASET
|
17 | 17 | - FILTER
|
| 18 | +- OCTREE |
18 | 19 | - STATE ESTIMATION
|
19 | 20 | - CALIBRATION
|
20 | 21 | - SIMULATION
|
@@ -5254,6 +5255,95 @@ def test_constant_acceleration_example(self):
|
5254 | 5255 | plt.show()
|
5255 | 5256 |
|
5256 | 5257 |
|
| 5258 | +############################################################################### |
| 5259 | +# OCTREE |
| 5260 | +############################################################################### |
| 5261 | + |
| 5262 | + |
| 5263 | +class OctreeNode: |
| 5264 | + def __init__(self, center, size, depth, max_depth): |
| 5265 | + self.center = center |
| 5266 | + self.size = size |
| 5267 | + self.depth = depth |
| 5268 | + self.max_depth = max_depth |
| 5269 | + self.children = [None for _ in range(8)] |
| 5270 | + self.data = [] |
| 5271 | + |
| 5272 | + def insert(self, point): |
| 5273 | + if self.depth == self.max_depth: |
| 5274 | + self.data.append(point) |
| 5275 | + return |
| 5276 | + |
| 5277 | + index = 0 |
| 5278 | + for i in range(3): |
| 5279 | + if point[i] < self.center[i]: |
| 5280 | + index |= (1 << i) |
| 5281 | + |
| 5282 | + offset_x = (-1)**(index&1) * self.size / 4.0 |
| 5283 | + offset_y = (-1)**((index>>1)&1) * self.size / 4.0 |
| 5284 | + offset_z = (-1)**((index>>2)&1) * self.size / 4.0 |
| 5285 | + |
| 5286 | + child = self.children[index] |
| 5287 | + if child is None: |
| 5288 | + new_center = self.center + np.array([offset_x, offset_y, offset_z]) |
| 5289 | + child = OctreeNode(new_center, self.size / 2.0, self.depth + 1, self.max_depth) |
| 5290 | + self.children[index] = child |
| 5291 | + |
| 5292 | + self.children[index].insert(point) |
| 5293 | + |
| 5294 | + |
| 5295 | +class Octree: |
| 5296 | + def __init__(self, points, max_depth=2): |
| 5297 | + self.center = np.array([0.0, 0.0, 0.0]) |
| 5298 | + self.size = 2.0 |
| 5299 | + self.root = OctreeNode(self.center, self.size, 0, max_depth) |
| 5300 | + for point in points: |
| 5301 | + self.root.insert(point) |
| 5302 | + |
| 5303 | + def get_points_and_bboxes(self, node, points_list, bboxes_list): |
| 5304 | + # Get points |
| 5305 | + if node.data: |
| 5306 | + points_list.extend(node.data) |
| 5307 | + |
| 5308 | + # Get bounding boxes |
| 5309 | + bboxes_list.append((node.center, node.size)) |
| 5310 | + |
| 5311 | + # DFS get points and bboxes |
| 5312 | + for child in node.children: |
| 5313 | + if child: |
| 5314 | + self.get_points_and_bboxes(child, points_list, bboxes_list) |
| 5315 | + |
| 5316 | + |
| 5317 | +class TestOctree(unittest.TestCase): |
| 5318 | + """ Test Octree """ |
| 5319 | + |
| 5320 | + def test_octree(self): |
| 5321 | + points = [np.random.rand(3) for _ in range(100)] |
| 5322 | + center = [0.0, 0.0, 0.0] |
| 5323 | + size = 100.0 |
| 5324 | + octree = Octree(points) |
| 5325 | + |
| 5326 | + octree_points = [] |
| 5327 | + octree_bboxes = [] |
| 5328 | + octree.get_points_and_bboxes(octree.root, octree_points, octree_bboxes) |
| 5329 | + |
| 5330 | + # Visualize octree |
| 5331 | + fig = plt.figure() |
| 5332 | + ax = fig.add_subplot(111, projection='3d') |
| 5333 | + |
| 5334 | + # -- Plot bounding boxes |
| 5335 | + for center, size in octree_bboxes: |
| 5336 | + plot_bbox(ax, center, [size, size, size]) |
| 5337 | + |
| 5338 | + # -- Plot points |
| 5339 | + for p in octree_points: |
| 5340 | + ax.plot(p[0], p[1], p[2], 'r.') |
| 5341 | + |
| 5342 | + plt.show() |
| 5343 | + |
| 5344 | + |
| 5345 | + |
| 5346 | + |
5257 | 5347 | ###############################################################################
|
5258 | 5348 | # STATE ESTIMATION
|
5259 | 5349 | ###############################################################################
|
|
0 commit comments