Skip to content

Instantly share code, notes, and snippets.

@yongjun21
Last active July 25, 2022 15:23
Show Gist options
  • Save yongjun21/17ebb9d041b0784e76c99e5cae0b6ac0 to your computer and use it in GitHub Desktop.
Save yongjun21/17ebb9d041b0784e76c99e5cae0b6ac0 to your computer and use it in GitHub Desktop.
Fast (vectorized) implementation of Octree encoding
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"import numpy as np \n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"nodes = np.zeros(3000000 * 8, np.uint32)\n",
"bit_values = 2 ** np.arange(8)\n",
"\n",
"def encode_octree(points, precision, min_range):\n",
" max_level = math.ceil(math.log2(min_range / precision))\n",
" num_points = points.shape[0]\n",
" \n",
" grid_size_0 = precision * 2 ** max_level\n",
" grid_size = grid_size_0\n",
" \n",
" paths = np.zeros((num_points, max_level + 1), np.uint32)\n",
" \n",
" x = points['x'] + grid_size_0 - precision / 2.0\n",
" y = points['y'] + grid_size_0 - precision / 2.0\n",
" z = points['z'] + grid_size_0 - precision / 2.0\n",
" for j in range(max_level):\n",
" x_plus = x >= grid_size\n",
" y_plus = y >= grid_size\n",
" z_plus = z >= grid_size\n",
" paths[:, j] = x_plus * 1 + y_plus * 2 + z_plus * 4\n",
" x -= x_plus * grid_size\n",
" y -= y_plus * grid_size\n",
" z -= z_plus * grid_size\n",
" grid_size /= 2.0\n",
" x_plus = x >= grid_size\n",
" y_plus = y >= grid_size\n",
" z_plus = z >= grid_size\n",
" paths[:, max_level] = x_plus * 1 + y_plus * 2 + z_plus * 4\n",
" \n",
" nodes[:8] = 0 \n",
" node_counts = [1]\n",
" last_count = 1\n",
" \n",
" current = np.zeros(num_points, np.uint32)\n",
" for j in range(max_level):\n",
" next_index = current * 8 + paths[:, j]\n",
" next_index_set = np.unique(next_index)\n",
" node_count = next_index_set.size\n",
" node_counts.append(node_count)\n",
" nodes[next_index_set] = np.arange(last_count, last_count + node_count)\n",
" nodes[(last_count * 8):((last_count + node_count) * 8)] = 0\n",
" last_count += node_count\n",
" current = nodes[next_index]\n",
" next_index = current * 8 + paths[:, max_level]\n",
" next_index_set = np.unique(next_index)\n",
" leaf_count = next_index_set.size\n",
" nodes[next_index_set] = last_count\n",
" df['leaf_index'] = next_index\n",
" \n",
" reshaped_nodes = nodes[:last_count * 8].reshape((-1, 8))\n",
" encoded = ((reshaped_nodes != 0) * bit_values).sum(axis = 1)\n",
" \n",
" # leaf values\n",
" grouped = df.groupby('leaf_index')\n",
" intensities = grouped['intensity'].max().to_numpy()\n",
" \n",
" return { 'precision': precision, 'node_counts': node_counts, 'leaf_count': leaf_count }, encoded, intensities"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment