Closed Frq-F closed 1 month ago
Hello,
The function pointGridSampling
in python returns an object of VertBitSet
type. You can use count()
method of it to find the number of samples.
If you want the result as numpy array, then you can export all points (before sampling) and sample mask:
from meshlib import mrmesh
from meshlib import mrmeshnumpy
# Start from numpy arrays
u, v = np.mgrid[0 : 2 * np.pi : 100j, 0 : np.pi : 100j]
x = np.cos(u) * np.sin(v)
y = np.sin(u) * np.sin(v)
z = np.cos(v)
# Prepare for MeshLib PointCloud
verts = np.stack((x.flatten(), y.flatten(), z.flatten()), axis=-1).reshape(-1, 3)
# Create MeshLib PointCloud from np ndarray
pc = mrmeshnumpy.pointCloudFromPoints(verts)
assert(pc.validPoints.count() == 10000)
# Sample points
samples = mrmesh.pointGridSampling(pc, 0.1)
assert(samples.count() == 1524)
# Convert all points (before downsampling) in numpy array
pts = mrmeshnumpy.toNumpyArray(pc.points)
# Convert sample mask in numpy array of True/False
mrmeshnumpy.getNumpyBitSet(samples)
Thank you for your suggestion, which has solved my problem. By the way, I want to know if there is a method to downsample the point cloud to a fixed number. for example, after sampling, the number of points in the point cloud is 5000.
I am trying to use a loop to downsample the point cloud to 5000 points. Here is my code:
def prepare(mesh):
verts = mesh.points
pc = mn.pointCloudFromPoints(verts)
while True:
samples = mm.pointGridSampling(pc, 0.99)
# Convert all points (before downsampling) in numpy array
pts = mn.toNumpyArray(pc.points)
# Convert sample mask in numpy array of True/False
samples_mask = mn.getNumpyBitSet(samples)
result = pts[np.where(samples_mask)[0]]
print(len(result))
tmp = len(result)
if tmp <= 5000:
break
pc = mn.pointCloudFromPoints(result)
But it only dropped to around 10000 and no longer undergoes downsampling. How to solve the problem?
The second parameter in pointGridSampling
is voxel size (or 3d box size), and the function leaves only one sample per voxel. If you run the function several times, then the voxels are the same and they already contain one point each, so the function does nothing. The only exception is the second run, which still removes some points because the bounding box of the whole point cloud changes after the first invocation, so the distribution of voxels changes as well.
In short, one has to increase voxelSize
to get smaller number of output samples.
As to receiving exactly specified number of samples, we have such option for meshes (see decimation), but not for point clouds yet.
Recently we introduced new function pointIterativeSampling
which allows one to get exact number of requested samples.
Hello ,I use the method pointGridSampling to downsample the pointcloud. Which python method can be used to check the number of points in the downsampled point cloud? And how to convert the downsampled point coordinates into numpy array