How to clean up the mesh in Open3D? - python

I created surface mesh from 3D cloud points using Open3D library in python. I have a lot of cases where the domains are similar to each other. For most of the cases, the open3D does a fine job in creating a closed surface mesh, but for few cases it creates some outlier meshes from the domain.
Below is the code for surface mesh from Open3D.
pcd = o3d.io.read_point_cloud('./mesh.xyz')
pcd.estimate_normals()
# to obtain a consistent normal orientation
pcd.orient_normals_towards_camera_location(pcd.get_center())
pcd.normals = o3d.utility.Vector3dVector( - np.asarray(pcd.normals))
# surface reconstruction using Poisson reconstruction
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=9)
o3d.io.write_triangle_mesh('mesh.stl', mesh)
I have attached pics of the outlier mesh obtained from the domain. How to clean those mesh from Open3D?. This occurs for only few of the test cases. We can easily see in the outlier image how the mesh is outside the domain.
Any leads will be appreciated.
Regards,
Sunag R A.

You can use Open3D Connected-components to remove outliers.
Example link -
http://www.open3d.org/docs/release/tutorial/geometry/mesh.html#Connected-components
Note - Please remove the duplicate vertices from mesh before using Connected-components.

Related

Points of the point cloud lying on 3D convex hull mesh

Is there a way to list all the points that lie on the convex hull (it is a 3d mesh) that is computed using the method compute_convex_hull of Open3D. I want to do further processing on the points that specifically lie on the the mesh that is the output of compute_convex_hull. The point cloud input and the output hull are in 3D space. So, any help on achieving this in Open3D? If not, are there any other geometry processing library that can help me achieve this?

Get a transparent colormap in 3D with Python

I have been looking for a Python library that would allow me, from a set of points in 3D and RGB colors associated to each point, to get a transparent surface (i. e., with some degree of transparency). The idea would be to be able to display (and manipulate/rotate) things similar to the image below:
The atoms and bonds are inside a 3D surface that is smooth and constructed from a series of points each with a RGB color.
I could get some rough Poisson reconstruction running with Mayavi but the colors appeared very pixelized and I couldn't find a way to make the surface transparent. I could obtain a lot of features I wanted for this work with Open3D (I actually place these objects inside crystal structures so I need to represent bonds, atoms, crystal edges, axes and so on), but here again I couldn't find a Poisson reconstruction algorithm to recreate the smooth surface from points nor any functionality to make a surface transparent. Any suggestion would be appreciated.

What is the use of Armadillo-meshes and knotMeshes in open3d?

Since I am still a beginner with open3d and still reading the documentation. Nowhere seems to be a clear explanation for Armadillo mesh class in open3d neither for knot mesh.
Why are they different types of meshes and what are the cases one should use them?
The reason behind the existence of these classes is explained in their GitHub repository as
The Dataset classes in Open3D are designed for convenient access to "built-in" example and test data.
Example usages of Armadillo mesh include surface deformations (ARAP), mesh optimization (Laplacian Mesh Optimization), skeleton extraction (Skeleton Extraction by Mesh Contraction), and key point detection (Intrinsic shape signatures (ISS)).
I haven't used a knot mesh before, but I believe that it is useful for applications in knot theory.
If you want to visualize the meshes and understand the difference better, you can do it the following way.
import open3d as o3d
knot_data = o3d.data.KnotMesh()
mesh = o3d.io.read_triangle_mesh(knot_data.path)
mesh.compute_vertex_normals() # for better visualization
o3d.visualization.draw_geometries([mesh])
armadillo_data = o3d.data.ArmadilloMesh()
mesh = o3d.io.read_triangle_mesh(armadillo_data.path)
o3d.visualization.draw_geometries([mesh])

Removing points that are occluded after perspective projection

I have a point cloud (.ply) and a projection matrix,
I've rendered the view from the first camera using the projection matrix and got this result: (python & opencv)
This is the original view:
Question: How can I render only the points that are seen from the particular viewpoint of the camera, in order not to see the occluded points?
I thought about converting it to a mesh w/ some surface reconstruction algorithm, and working with the mesh, like generating an occlusion map. Any ideas?
Implicit Surface Octrees (https://www.cse.iitb.ac.in/~rhushabh/publications/icvgip10/icvgip10.pdf) can be used to reconstruct the surface and visualize point clouds. Recent advances in real-time point cloud rendering have been achieved with this method. An overview of developments in this area can be found in this article - https://trepo.tuni.fi/bitstream/handle/10024/117953/KiviPetrus.pdf?sequence=2&isAllowed=y. In it, you can also find other approaches to solving this problem.
After building the octree, you get the ability to drop non-rendered points and render the surface with texturing and shading.
An experimental method for drawing only points. Here I mean that you want to draw the frame once, so this method works asymptotically O (N) and in the worst case O (P * N), where P is the number of pixels on the screen (when the points are too far / close (depending from the implementation) and the rendering queue from far to near). To optimize and obtain stable asymptotics for some input data, it may be useful to sort by distance from the camera.
Convert the coordinates of the points to 2D screen space.
create Z-buffer
for each point
if the coordinate in Z-buffer is closer to the viewer than for this point - skip (continue)
draw a dot on the screen
instead of marking one pixel in the Z-buffer, draw a circle in it (possibly with a radial gradient) with a radius depending on the distance (something like a distance * eps, where eps - you can use the angle in radians between two projection points on the screen)
Profit!
Fast and easy, but I've never done that, so I don't know how well it works.
Translated by Google Translate

python: scipy.spatial: draw a convex polygon and calculate the area

I am using python. Now I have some coordinates (earth plane coordinates) and I want to draw a convex polygon based on these coordinates. Besides, I need to save the polygon into a GeoJSON format and calculate the polygon area.
I heard that scipy.spatial can do this but I have no idea how to do that, besides, how to extract the polygon coordinates and calculate the area on earth?
Thanks
As far as I know, scipy.spatial does not include the functions you need.
GeoPandas would be suitable for this task. See for instance this example for calculating areas of a polynomial. It also allows to convert between different coordinates system and support output to GeoJSON format.

Categories