{"id":16320249,"url":"https://github.com/meyerls/pc-skeletor","last_synced_at":"2025-04-07T07:12:07.192Z","repository":{"id":63530181,"uuid":"567782688","full_name":"meyerls/pc-skeletor","owner":"meyerls","description":"Skeletonization of 3D Point Clouds","archived":false,"fork":false,"pushed_at":"2024-05-14T08:32:54.000Z","size":73567,"stargazers_count":150,"open_issues_count":13,"forks_count":18,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-29T09:20:45.260Z","etag":null,"topics":["3d-skeleton","laplacian","lbc","pointcloud","python","s-lbc","skeleton-extraction","skeletonization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meyerls.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-18T15:08:58.000Z","updated_at":"2024-10-21T02:22:05.000Z","dependencies_parsed_at":"2024-05-14T09:41:24.862Z","dependency_job_id":"3c56a4a0-10b3-4fd3-be9b-7c3bcc6dcfb4","html_url":"https://github.com/meyerls/pc-skeletor","commit_stats":{"total_commits":82,"total_committers":4,"mean_commits":20.5,"dds":0.2195121951219512,"last_synced_commit":"37a1cc7f5cdc0b5d29a6381e9e042722349ecd3d"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyerls%2Fpc-skeletor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyerls%2Fpc-skeletor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyerls%2Fpc-skeletor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meyerls%2Fpc-skeletor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meyerls","download_url":"https://codeload.github.com/meyerls/pc-skeletor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247608153,"owners_count":20965952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-skeleton","laplacian","lbc","pointcloud","python","s-lbc","skeleton-extraction","skeletonization"],"created_at":"2024-10-10T22:43:40.316Z","updated_at":"2025-04-07T07:12:07.171Z","avatar_url":"https://github.com/meyerls.png","language":"Python","readme":"# PC Skeletor - Point Cloud Skeletonization \u003cimg align=\"right\" height=\"250\" src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/PCSkeletor.png\"\u003e\r\n\r\n\u003ca href=\"https://pypi.org/project/pc-skeletor/\"\u003e\u003cimg alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/pc-skeletor\"\u003e\u003c/a\u003e\r\n\u003ca href=\"https://pypi.org/project/pc-skeletor/\"\u003e\u003cimg alt=\"PyPI - Python Version\" src=\"https://img.shields.io/pypi/pyversions/pc-skeletor\"\u003e\u003c/a\u003e\r\n\u003ca href=\"https://github.com/meyerls/pc-skeletor/blob/main/LICENSE\"\u003e\u003cimg alt=\"license\" src=\"https://img.shields.io/github/license/meyerls/pc-skeletor\"\u003e\u003c/a\u003e\r\n\u003c!--a href=\"https://github.com/meyerls/pc-skeletor/actions\"\u003e\u003cimg alt=\"GitHub Workflow Status\" src=\"https://img.shields.io/github/workflow/status/meyerls/pc-skeletor/Python%20package\"\u003e\u003c/a--\u003e\r\n\r\n**PC Skeletor** is a Python library for extracting a curved skeleton from 3d point clouds using\r\n[Laplacian-Based Contraction](https://taiya.github.io/pubs/cao2010cloudcontr.pdf) and\r\n[Semantic Laplacian-Based Contraction](https://arxiv.org/abs/2304.04708).\r\n\r\n## Abstract\r\nBasic Laplacian-based contraction (LBC) is prone to mal-contraction in cases where\r\nthere is a significant disparity in diameter between trunk and branches. In such cases fine structures experience \r\nan over-contraction and leading to a distortion of their topological characteristics. In addition, LBC shows a \r\ntopologically incorrect tree skeleton for trunk structures that have holes in the point cloud.In order to address \r\nthese topological artifacts, we introduce semantic Laplacian-based contraction (S-LBC). It integrates semantic \r\ninformation of the point cloud into the contraction algorithm to overcome these artifacts.\r\n\r\n\r\n\u003ctable\u003e\r\n  \u003ctr\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n        \u003ch4\u003eLaplacian-Based Contraction (LBC)\u003c/h4\u003e\r\n        \u003cimg src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/lbc.gif\" alt=\"Image 1\"\u003e\r\n    \u003c/td\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n        \u003ch4\u003eSemantic LBC (S-LBC)\u003c/h4\u003e\r\n        \u003cimg src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/s_lbc.gif\" alt=\"Image 2\"\u003e\r\n    \u003c/td\u003e\r\n  \u003c/tr\u003e\r\n\u003c/table\u003e\r\n\r\n## ⚡️ Quick Start\r\n\r\n### Installation\r\n\r\nFirst install [Python](https://www.python.org/downloads/) Version 3.8 or higher. The python package can be installed\r\nvia [PyPi](https://pypi.org/project/pc-skeletor/) using pip.\r\n\r\n ````sh\r\npip install pc-skeletor\r\n ````\r\n\r\n### Installation from Source\r\n\r\n ````sh\r\ngit clone https://github.com/meyerls/pc-skeletor.git\r\ncd pc-skeletor\r\npip install --upgrade pip setuptools\r\npip install -r requirements.txt\r\npip install -e .\r\n ````\r\n\r\n### Basic Usage\r\n\r\nThe following code performs the skeletonization algorithm on a downloaded point cloud example. It also generates an \r\nanimation that includes the original point cloud and the resulting skeleton, which is exported as a gif.\r\n\r\n\r\n#### Download Example Dataset\r\n\r\n````python\r\nimport open3d as o3d\r\nimport numpy as np\r\n\r\nfrom pc_skeletor import Dataset\r\n\r\ndownloader = Dataset()\r\ntrunk_pcd_path, branch_pcd_path = downloader.download_semantic_tree_dataset()\r\n\r\npcd_trunk = o3d.io.read_point_cloud(trunk_pcd_path)\r\npcd_branch = o3d.io.read_point_cloud(branch_pcd_path)\r\npcd = pcd_trunk + pcd_branch\r\n````\r\n\r\n#### Laplacian-Based Contraction (LBC)\r\n\r\n````python\r\nfrom pc_skeletor import LBC\r\n\r\nlbc = LBC(point_cloud=pcd,\r\n          down_sample=0.008)\r\nlbc.extract_skeleton()\r\nlbc.extract_topology()\r\n\r\n# Debug/Visualization\r\nlbc.visualize()\r\nlbc.export_results('./output')\r\nlbc.animate(init_rot=np.asarray([[1, 0, 0], [0, 0, 1], [0, 1, 0]]),\r\n            steps=300,\r\n            output='./output')\r\n````\r\n\r\n#### Semantic Laplacian-Based Contraction (S-LBC)\r\n\r\n````python\r\nfrom pc_skeletor import SLBC\r\n\r\ns_lbc = SLBC(point_cloud={'trunk': pcd_trunk, 'branches': pcd_branch},\r\n             semantic_weighting=30,\r\n             down_sample=0.008,\r\n             debug=True)\r\ns_lbc.extract_skeleton()\r\ns_lbc.extract_topology()\r\n\r\n# Debug/Visualization\r\ns_lbc.visualize()\r\ns_lbc.show_graph(s_lbc.skeleton_graph)\r\ns_lbc.show_graph(s_lbc.topology_graph)\r\ns_lbc.export_results('./output')\r\ns_lbc.animate(init_rot=np.asarray([[1, 0, 0], [0, 0, 1], [0, 1, 0]]), steps=300, output='./output')\r\n````\r\n\r\n#### Output\r\n\r\n\u003ctable\u003e\r\n  \u003ctr\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n        Skeleton\r\n        \u003cimg src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/contracted_cropped.gif\" width=\"170px\"\u003e\r\n    \u003c/td\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n        Topology \r\n        \u003cimg src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/topology_cropped.gif\" width=\"170px\"\u003e\r\n    \u003c/td\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n        Skeletal Graph\r\n        \u003cimg src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/topology_graph_cropped.png\" width=\"600px\"\u003e\r\n    \u003c/td\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n        Topology Graph\r\n        \u003cimg src=\"https://media.githubusercontent.com/media/meyerls/pc-skeletor/slbc/img/skeletal_graph_cropped.png\" width=\"600px\"\u003e\r\n    \u003c/td\u003e\r\n  \u003c/tr\u003e\r\n\u003c/table\u003e\r\n\r\n````python\r\nlbc.contracted_point_cloud: o3d.geometry.PointCloud\r\nlbc.skeleton: o3d.geometry.PointCloud\r\nlbc.skeleton_graph: networkx.nx\r\nlbc.topology: o3d.geometry.LineSet\r\nlbc.topology_graph: networkx.nx\r\n````\r\n\r\n## Ω Parametrization\r\n\r\n### Laplacian-Based Contraction\r\n\r\nLaplacian-Based Contraction is a method based on contraction of point clouds to extract curve skeletons by iteratively\r\ncontracting the point cloud. This method is robust to missing data and noise. Additionally no prior knowledge on the\r\ntopology of the object has to be made.\r\n\r\nThe contraction is computed by iteratively solving the linear system\r\n\r\n```math\r\n\\begin{bmatrix}\r\n\\mathbf{W_L} \\mathbf{L}\\\\\r\n\\mathbf{W_H}\r\n\\end{bmatrix} \\mathbf{P}^{'} =\r\n\\begin{bmatrix}\r\n\\mathbf{0}\\\\\r\n\\mathbf{W_H} \\mathbf{P}\r\n\\end{bmatrix}\r\n```\r\n\r\nobtained from [Kin-Chung Au et al.](http://graphics.csie.ncku.edu.tw/Skeleton/skeleton-paperfinal.pdf)\r\n$\\mathbf{L}$ is the $n \\times n$\r\n[Laplacian Matrix](http://rodolphe-vaillant.fr/entry/101/definition-laplacian-matrix-for-triangle-meshes)\r\nwith cotangent weights. The Laplacian of a point cloud (Laplace-Beltrami Operator) can be used to compute the [mean\r\ncurvature Vector](http://www.cs.cmu.edu/~kmcrane/Projects/DDG/paper.pdf)(p. 88 \u0026 p. 100). $\\mathbf{P}$ is the original\r\npoint cloud, $\\mathbf{P}^{'}$ a contracted point cloud and $\\mathbf{W_L}$ and $\\mathbf{W_H}$ are diagonal weight\r\nmatrices balancing the contraction and attraction forces. During the contraction the point clouds get thinner and\r\nthinner until the solution converges. Afterwards the contracted point cloud aka. skeleton is sampled using\r\nfarthest-point method.\r\n\r\nTo archive good contraction result and avoid over- and under-contraction it is necessary to initialize and update the\r\nweights $\\mathbf{W_L}$ and $\\mathbf{W_H}$. Therefore the initial values and the maximum values for both diagonal\r\nweighting matrices have to adjusted to archive good results.\r\n\r\n#### Semantic Laplacian-Based Contraction\r\n\r\nSemantic Laplacian-Based Contraction is based on Laplacian-based contraction and simply adds semantic knowledge to the\r\nskeletonization algorithm.\r\n\r\n```math\r\n\\begin{bmatrix}\r\n\\mathbf{S} \\circ \\mathbf{W_L} \\mathbf{L}\\\\\r\n\\mathbf{W_H}\r\n\\end{bmatrix} \\mathbf{P}^{'} =\r\n\\begin{bmatrix}\r\n\\mathbf{0}\\\\\r\n\\mathbf{W_H} \\mathbf{P}\r\n\\end{bmatrix}\r\n```\r\n\r\nStandard LBC is prone to mal-contraction in cases where there is a significant disparity in\r\ndiameter between trunk and branches. In such cases fine structures experience an over- contraction and leading to a\r\ndistortion of their topological characteristics. In order to address these topological artifacts, we introduce semantic\r\nLaplacian-based contraction (S-LBC). For more information please refer to the [[Paper](https://google.de)].\r\n\r\n## 📖 Literature and Code used for implementation\r\n\r\n#### Laplacian based contraction\r\n\r\nOur implementation\r\nof [Point Cloud Skeletons via Laplacian-Based Contraction](https://taiya.github.io/pubs/cao2010cloudcontr.pdf) is a\r\npython reimplementation of the original [Matlab code](https://github.com/taiya/cloudcontr).\r\n\r\n#### Robust Laplacian for Point Clouds\r\n\r\nComputation of the discrete laplacian operator\r\nvia [Nonmanifold Laplace](http://www.cs.cmu.edu/~kmcrane/Projects/NonmanifoldLaplace/NonmanifoldLaplace.pdf) can be\r\nfound in the [robust-laplacians-py](https://github.com/nmwsharp/robust-laplacians-py) repository.\r\n\r\n#### Minimum Spanning Tree\r\n\r\nThe Minimum Spanning Tree is computed via  [Mistree](https://arxiv.org/pdf/1910.08562.pdf) a\r\nopen-source implementation which can be found [here](https://github.com/knaidoo29/mistree).\r\n\r\n## :interrobang: Troubleshooting\r\n\r\nFor Windows users, there might be issues installing the `mistree` library via `python -m pip install mistree` command.\r\nIf you get an error message that the Fortran compiler cannot be found, please try the following:\r\n\r\n- Download and install this suite of compilation tools: http://www.equation.com/servlet/equation.cmd?fa=fortran\r\n- Add the `bin` folder in the installation directory to your `PATH` environment variable\r\n- After restarting your terminal and now trying to install `mistree` this should work now.\r\n- However, upon importing the library you might face an issue with missing DLL files. You simply need to copy or move\r\n  them within the `mistree` installation directory, as explained\r\n  here: https://github.com/knaidoo29/mistree/issues/14#issuecomment-1275022276\r\n- Now the PC-Skeletor should be running on your Windows machine.\r\n\r\n## :heavy_exclamation_mark: Limitation / Improvements\r\n\r\n- [ ] Implement [Point2Skeleton](https://arxiv.org/pdf/2012.00230.pdf)\r\n- [ ] Implement [L1-Medial Skeleton](https://www.cs.sfu.ca/~haoz/pubs/huang_sig13_l1skel.pdf) \r\n- [ ] Test code\r\n- [ ] Improve graph representation\r\n\r\n# 📖 Citation\r\n\r\nPlease cite this [[Paper](https://arxiv.org/abs/2304.04708)] if this work helps you with your research:\r\n\r\n```\r\n@misc{meyer2023cherrypicker,\r\n      title={CherryPicker: Semantic Skeletonization and Topological Reconstruction of Cherry Trees}, \r\n      author={Lukas Meyer and Andreas Gilson and Oliver Scholz and Marc Stamminger},\r\n      year={2023},\r\n      eprint={2304.04708},\r\n      archivePrefix={arXiv},\r\n      primaryClass={cs.CV}\r\n}\r\n```\r\n\r\n\r\n\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeyerls%2Fpc-skeletor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeyerls%2Fpc-skeletor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeyerls%2Fpc-skeletor/lists"}