{"id":2157,"date":"2021-08-16T11:42:13","date_gmt":"2021-08-16T03:42:13","guid":{"rendered":"http:\/\/www.yatenglg.cn\/?p=2157"},"modified":"2022-10-18T16:34:39","modified_gmt":"2022-10-18T08:34:39","slug":"open3d-octree","status":"publish","type":"post","link":"https:\/\/www.yatenglg.cn\/blog\/?p=2157","title":{"rendered":"open3d-octree"},"content":{"rendered":"\n<h1>open3d\u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e13\u95e8\u7528\u4e8e\u516b\u53c9\u6811\u7684\u6570\u636e\u7ed3\u6784 <strong>Octree<\/strong>\u3002<\/h1>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-python\" data-lang=\"Python\"><code>class Octree(Geometry3D):\n    max_depth\n    origin\n    root_node\n    size\n    def convert_from_point_cloud(self, point_cloud, size_expand=0.01): \n    def create_from_voxel_grid(self):\n    def insert_point(self, point, f_init, f_update, fi_init=None, fi_update=None):\n    def is_point_in_bound(self, point, origin, size):\n    # \u5f53\u524d\u8282\u70b9\u7684\u5b50\u8282\u70b9\n    def locate_leaf_node(self, point):\n    def to_voxel_grid(self):\n    def traverse(self, f, *args, **kwargs):<\/code><\/pre><\/div>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-python\" data-lang=\"Python\"><code>class OctreeInternalPointNode(OctreeInternalNode):\n    children  # \u5b50\u8282\u70b9\n    indices   # \u4e0b\u6807\n    def __init__(self, *args, **kwargs):\n        &quot;&quot;&quot;\n        __init__(*args, **kwargs)\n        Overloaded function.\n        1. __init__(self)\n            Default constructor\n        2. __init__(self, arg0)\n            Copy constructor\n        Args:\n            arg0 (open3d.geometry.OctreeInternalPointNode)\n        &quot;&quot;&quot;\n    def get_init_function(self):\n    def get_update_function(self, arg0):\n    def __copy__(self):\n    def __deepcopy__(self, arg0):<\/code><\/pre><\/div>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-python\" data-lang=\"Python\"><code>class OctreeNodeInfo(__pybind11_builtins.pybind11_object):\n    child_index\n    depth\n    origin\n    size\n    def __init__(self, origin, size, depth, child_index):\n        &quot;&quot;&quot;\n        __init__(self, origin, size, depth, child_index)\n\n        Args:\n            origin (numpy.ndarray[float64[3, 1]])\n            size (float)\n            depth (int)\n            child_index (int)\n        &quot;&quot;&quot;<\/code><\/pre><\/div>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-plain\"><code>import open3d as o3d\nimport numpy as np\nfrom open3d.web_visualizer import draw\nfrom open3d.visualization import draw_geometries<\/code><\/pre><\/div>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-plain\"><code>pcd = o3d.io.read_point_cloud(&#39;datas\/sphere.ply&#39;)\nprint(pcd)\n-&gt; PointCloud with 642 points.\ndraw(pcd)<\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"421\" height=\"377\" src=\"http:\/\/www.yatenglg.cn\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-DA3E80-1.png\" alt=\"\" class=\"wp-image-2178\" srcset=\"https:\/\/www.yatenglg.cn\/blog\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-DA3E80-1.png 421w, https:\/\/www.yatenglg.cn\/blog\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-DA3E80-1-300x269.png 300w\" sizes=\"(max-width: 421px) 100vw, 421px\" \/><\/figure>\n\n\n\n<h2>1. \u4ece\u70b9\u4e91\u6784\u5efa\u516b\u53c9\u6811<\/h2>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-python\" data-lang=\"Python\"><code>oct = o3d.geometry.Octree(max_depth=4)\noct.convert_from_point_cloud(pcd)\nprint(oct)\n-&gt; Octree with origin: [-1, -1, -1], size: 2.02, max_depth: 4\ndraw(oct)<\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"477\" height=\"382\" src=\"http:\/\/www.yatenglg.cn\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-QS2E80.png\" alt=\"\" class=\"wp-image-2179\" srcset=\"https:\/\/www.yatenglg.cn\/blog\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-QS2E80.png 477w, https:\/\/www.yatenglg.cn\/blog\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-QS2E80-300x240.png 300w\" sizes=\"(max-width: 477px) 100vw, 477px\" \/><\/figure>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-plain\"><code>print(oct.root_node)\n-&gt; OctreeInternalPointNode with 8 non-empty child nodes and 642 points\nprint(oct.root_node.children[0])\n-&gt; OctreeInternalPointNode with 7 non-empty child nodes and 93 points<\/code><\/pre><\/div>\n\n\n\n<h2>2. \u516b\u53c9\u6811\u7d22\u5f15<\/h2>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-plain\"><code># \u53d6\u516b\u53c9\u6811\u7b2c\u4e00\u5c42\u7684\u7b2c\u56db\u90e8\u5206\u4e2d\u7684\u70b9\u4e91\uff0c\u6d82\u6210\u7ea2\u8272\noct_4 = pcd.select_by_index(oct.root_node.children[4].indices)\noct_4.paint_uniform_color([1,0,0])\noct_e = pcd.select_by_index(oct.root_node.children[4].indices, True)\noct_e.paint_uniform_color([0,0,0])\ndraw([oct_4, oct_e])<\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"329\" height=\"246\" src=\"http:\/\/www.yatenglg.cn\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-06ZT70.png\" alt=\"\" class=\"wp-image-2180\" srcset=\"https:\/\/www.yatenglg.cn\/blog\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-06ZT70.png 329w, https:\/\/www.yatenglg.cn\/blog\/wp-content\/uploads\/2021\/08\/gnome-shell-screenshot-06ZT70-300x224.png 300w\" sizes=\"(max-width: 329px) 100vw, 329px\" \/><\/figure>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-plain\"><code># \u8fd4\u56de\u6307\u5b9a\u70b9\u5728\u516b\u53c9\u6811\u4e2d\u7684\u53f6\u8282\u70b9 \u4ee5\u53ca\u8be5\u70b9\u6240\u5728\u7684\u5185\u90e8\u8282\u70b9\u4fe1\u606f\nleafnode, nodeinfo = oct.locate_leaf_node(pcd.points[0])\nprint(leafnode)\n-&gt; OctreePointColorLeafNode with color [0, 0, 0] containing 1 points.\nprint(nodeinfo) # \n-&gt; OctreeNodeInfo with origin [0.38875, 0.89375, 0.01], size 0.12625, depth 4, child_index 3\nprint(pcd.points[0]) # \u7b2c\u4e00\u4e2a\u70b9\u7684\u5750\u6807\n-&gt; [0.39960703 0.91298246 0.08232358]\nprint(oct.origin) # \u516b\u53c9\u6811\u5750\u6807\u8f74\u6700\u5c0f\u503c\n-&gt; [-1. -1. -1.]\nprint(oct.size)  # \u516b\u53c9\u6811\n-&gt; 2.02<\/code><\/pre><\/div>\n\n\n\n<h2>2. \u516b\u53c9\u6811\u56de\u8c03<\/h2>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-python\" data-lang=\"Python\"><code>def callback(node, node_info):\n    if isinstance(node, o3d.geometry.OctreeInternalNode): # \u5185\u90e8\u8282\u70b9\n        if isinstance(node, o3d.geometry.OctreeInternalPointNode):\n            # for child in node.children:\n            depth = node_info.depth\n            child_num = len([child for child in node.children if child is not None])\n            point_num = len(node.indices)\n            print(&#39;{} depth: {} | index: {} | child num: {} | point num: {}&#39;.format(&#39;- &#39;*depth, depth, node_info.child_index, child_num, point_num))\n    if isinstance(node, o3d.geometry.OctreeLeafNode): # \u53f6\u8282\u70b9\n        if isinstance(node, o3d.geometry.OctreePointColorLeafNode):\n            pass\noct.traverse(callback)<\/code><\/pre><\/div>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-plain\"><code> depth: 0 | index: 0 | child num: 8 | point num: 642\n-  depth: 1 | index: 0 | child num: 7 | point num: 93\n- -  depth: 2 | index: 0 | child num: 1 | point num: 3\n- - -  depth: 3 | index: 7 | child num: 3 | point num: 3\n- -  depth: 2 | index: 1 | child num: 6 | point num: 14\n- - -  depth: 3 | index: 2 | child num: 1 | point num: 1\n- - -  depth: 3 | index: 3 | child num: 2 | point num: 4\n- - -  depth: 3 | index: 4 | child num: 1 | point num: 1\n- - -  depth: 3 | index: 5 | child num: 2 | point num: 3\n- - -  depth: 3 | index: 6 | child num: 3 | point num: 3\n- - -  depth: 3 | index: 7 | child num: 2 | point num: 2\n- -  depth: 2 | index: 2 | child num: 6 | point num: 14\n......<\/code><\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>open3d\u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e13\u95e8\u7528\u4e8e\u516b\u53c9\u6811\u7684\u6570\u636e\u7ed3\u6784 Octree\u3002 1. \u4ece\u70b9\u4e91\u6784\u5efa\u516b\u53c9\u6811 2. \u516b\u53c9\u6811\u7d22\u5f15 2&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[22],"tags":[],"_links":{"self":[{"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2157"}],"collection":[{"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2157"}],"version-history":[{"count":20,"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2157\/revisions"}],"predecessor-version":[{"id":2181,"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2157\/revisions\/2181"}],"wp:attachment":[{"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yatenglg.cn\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}