# Alphamorph
**alphamorph** is a Python package for non-rigid transformations of point clouds.
Unlike the traditional usage of **registration** between a source and a target, alphamorph transforms a source point cloud into a target **shape**, in this case a circle.
This is done by finding alpha shapes, that will be used as anchors for thin-plate splines.
In layman terms, it is "making the bed" by 1) finding where are the bed corners and 2) pushing and pulling the sheets!
## Features
- **Point Cloud Transformation:** Given a noisy point cloud, apply a non-rigid transformation so it fits a shape
- **Visualization:** Easily visualize the original, distorted, and transformed point clouds.
## Installation
You can install **alphamorph** via pip:
```bash
pip install alphamorph
```
## Minimal Working Example
````python
import numpy as np
from alphamorph.apply import alphamorph_apply
points = np.random.rand(1000, 2)
new_points = alphamorph_apply(points, alpha=2.5)
````
## Full Example
Below is a simple example that demonstrates how to use **alphamorph** to transform a point cloud:
````python
import numpy as np
import matplotlib.pyplot as plt
from alphamorph.geometry import generate_point_cloud, distort_point_cloud
from alphamorph.alpha import compute_alpha_shape
from alphamorph.apply import alphamorph_apply
from alphamorph.plotting import plot_point_cloud, create_color_list
np.random.seed(42)
# Generate an original point cloud and a distorted version
original_points = generate_point_cloud(num_points=2000)
color_list = create_color_list(original_points)
noisy_points = distort_point_cloud(original_points, noise_scale=0.2, num_bins=15)
# Compute alpha shapes and apply alphamorph transformation
alpha = 2.5
original_hull_indices, original_hull_points = compute_alpha_shape(original_points, alpha)
reconstructed_hull_indices, reconstructed_hull_points = compute_alpha_shape(noisy_points, alpha)
new_points = alphamorph_apply(original_points, alpha=alpha)
new_points_hull_points = new_points[reconstructed_hull_indices]
# Plot
fig, axes = plt.subplots(1, 3, figsize=(12, 6))
plot_point_cloud(axes[0], original_points, 'Original', color_list=color_list, hull_points=original_hull_points)
plot_point_cloud(axes[1], noisy_points, 'Noisy', color_list=color_list, hull_points=reconstructed_hull_points)
plot_point_cloud(axes[2], new_points, 'Noisy + Alphamorph', color_list=color_list, hull_points=new_points_hull_points)
plt.tight_layout()
plt.savefig('alphamorph_example.png')
plt.show()
````
## Example Results
<img src="alphamorph_example.png" alt="Alphamorph Example" width="2000">
Raw data
{
"_id": null,
"home_page": "https://github.com/DavidFernandezBonet/alphamorph",
"name": "alphamorph",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": null,
"author": "David Fernandez Bonet",
"author_email": "davferdz@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/fd/70/d2e625068604312b3b8f42d1a1cd6d36ac899403937c234b7b9b8f743fdc/alphamorph-0.3.tar.gz",
"platform": null,
"description": "# Alphamorph\n\n**alphamorph** is a Python package for non-rigid transformations of point clouds. \n\nUnlike the traditional usage of **registration** between a source and a target, alphamorph transforms a source point cloud into a target **shape**, in this case a circle.\n\nThis is done by finding alpha shapes, that will be used as anchors for thin-plate splines. \n\nIn layman terms, it is \"making the bed\" by 1) finding where are the bed corners and 2) pushing and pulling the sheets!\n\n## Features\n- **Point Cloud Transformation:** Given a noisy point cloud, apply a non-rigid transformation so it fits a shape\n- **Visualization:** Easily visualize the original, distorted, and transformed point clouds.\n\n## Installation\n\nYou can install **alphamorph** via pip:\n\n```bash\npip install alphamorph\n```\n\n## Minimal Working Example\n````python\nimport numpy as np\nfrom alphamorph.apply import alphamorph_apply\npoints = np.random.rand(1000, 2)\nnew_points = alphamorph_apply(points, alpha=2.5)\n````\n\n## Full Example\n\nBelow is a simple example that demonstrates how to use **alphamorph** to transform a point cloud:\n\n````python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom alphamorph.geometry import generate_point_cloud, distort_point_cloud\nfrom alphamorph.alpha import compute_alpha_shape\nfrom alphamorph.apply import alphamorph_apply\nfrom alphamorph.plotting import plot_point_cloud, create_color_list\n\n\nnp.random.seed(42)\n\n# Generate an original point cloud and a distorted version\noriginal_points = generate_point_cloud(num_points=2000)\ncolor_list = create_color_list(original_points)\nnoisy_points = distort_point_cloud(original_points, noise_scale=0.2, num_bins=15)\n\n\n\n# Compute alpha shapes and apply alphamorph transformation\nalpha = 2.5\noriginal_hull_indices, original_hull_points = compute_alpha_shape(original_points, alpha)\nreconstructed_hull_indices, reconstructed_hull_points = compute_alpha_shape(noisy_points, alpha)\nnew_points = alphamorph_apply(original_points, alpha=alpha)\nnew_points_hull_points = new_points[reconstructed_hull_indices]\n\n# Plot\nfig, axes = plt.subplots(1, 3, figsize=(12, 6))\nplot_point_cloud(axes[0], original_points, 'Original', color_list=color_list, hull_points=original_hull_points)\nplot_point_cloud(axes[1], noisy_points, 'Noisy', color_list=color_list, hull_points=reconstructed_hull_points)\nplot_point_cloud(axes[2], new_points, 'Noisy + Alphamorph', color_list=color_list, hull_points=new_points_hull_points)\nplt.tight_layout()\nplt.savefig('alphamorph_example.png')\nplt.show()\n````\n\n\n## Example Results\n\n<img src=\"alphamorph_example.png\" alt=\"Alphamorph Example\" width=\"2000\">\n\n\n\n\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Morph point clouds into circular shapes using alpha shapes and thin-plate splines.",
"version": "0.3",
"project_urls": {
"Homepage": "https://github.com/DavidFernandezBonet/alphamorph"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "dca3089e80bccd935b810d28b4648e6391a155afbfffb095062be776edd09493",
"md5": "62b185931577238519f3d750d777441d",
"sha256": "f4e180ef51fddbc35d981bfa8297f36d83be12a97e52b411ec130b76c9adc41b"
},
"downloads": -1,
"filename": "alphamorph-0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "62b185931577238519f3d750d777441d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 12834,
"upload_time": "2025-03-03T16:13:25",
"upload_time_iso_8601": "2025-03-03T16:13:25.182356Z",
"url": "https://files.pythonhosted.org/packages/dc/a3/089e80bccd935b810d28b4648e6391a155afbfffb095062be776edd09493/alphamorph-0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "fd70d2e625068604312b3b8f42d1a1cd6d36ac899403937c234b7b9b8f743fdc",
"md5": "6f3fd7bd1b4ea40af92e48edcfb8609e",
"sha256": "fbecdac82f38aab2dfbfc6602491b4a10b2f6a770d2eff5386d15b8a35f1bdfe"
},
"downloads": -1,
"filename": "alphamorph-0.3.tar.gz",
"has_sig": false,
"md5_digest": "6f3fd7bd1b4ea40af92e48edcfb8609e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 10539,
"upload_time": "2025-03-03T16:13:26",
"upload_time_iso_8601": "2025-03-03T16:13:26.979106Z",
"url": "https://files.pythonhosted.org/packages/fd/70/d2e625068604312b3b8f42d1a1cd6d36ac899403937c234b7b9b8f743fdc/alphamorph-0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-03-03 16:13:26",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "DavidFernandezBonet",
"github_project": "alphamorph",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "alphamorph"
}