Beispiel #1
0
def compute_normal_and_curvature(points, k = 30):
    """
    Args:
        points: pointcloud-Nx3
        k: number of pointset

    Returns:
        data = [x, y, z, nx, ny, nz, curvature]
    """
    assert points.shape[1] == 3
    points = pd.DataFrame(points)
    points.columns = ['x', 'y', 'z']
    cloud = PyntCloud(points)

    k_neighbors = cloud.get_neighbors(k=k)
    cloud_normal = copy.copy(cloud)
    cloud_normal = cloud_normal.add_scalar_field("normals", k_neighbors=k_neighbors)
    ev = copy.copy(cloud)
    ev = cloud.add_scalar_field("eigen_values", k_neighbors=k_neighbors)
    cloud.add_scalar_field("curvature", ev=ev)
    points = cloud.points
    nx = "nx(" + (k + 1).__str__() + ")"
    ny = "ny(" + (k + 1).__str__() + ")"
    nz = "nz(" + (k + 1).__str__() + ")"
    curvature = "curvature(" + (k + 1).__str__() + ")"

    filter_columns = ['x', 'y', 'z', nx, ny, nz, curvature]
    data = points.reindex(columns=filter_columns)
    return data
class CorrespondingLidarPointCloud():
    def __init__(self, pcl_path, pointsensor):
        self._points = np.fromfile(str(pcl_path), dtype=np.float32).reshape((-1, 5))[:, :3]
        self._pointsensor = pointsensor
        self._pc = PyntCloud(self._points.T) #[3, N] -> [N, 3]

    def getPointCloud(self):
        return self._points

    def getPointsensor(self):
        return self._pointsensor

    def getOccupancyMatrix(self, as_tensor=True):
        assert self._occupancy, "Call voxelize() first"

        if as_tensor:
            return torch.tensor(self._occupancy)

        return self._occupancy

    def getNeighbors(self):
        assert self._neighbors, "Call generateKNN() first"
        return self._neighbors

    def getKNN(self, k):
        return self._pc.get_neighbors(k=k)

    def nbr_points(self) -> int:
        return self._points.shape[1]

    def voxelize(self, size_x, size_y, size_z):
        voxelgrid_id = self._pc.add_structure("voxelgrid", size_x=size_x, size_y=size_y, size_z=size_z, regular_bounding_box=False)
        voxelgrid = self._pc.structures[voxelgrid_id]
        self._occupancy = voxelgrid.get_feature_vector(mode='binary')

    def generateKNN(self):
        self._neighbors = self._pc.get_neighbors() #(N, k)

    def translate(self, x):
        for i in range(3):
            self._points[i, :] = self._points[i, :] + x[i]

    def rotate(self, rot_matrix):
        self._points = np.dot(rot_matrix, self._points)

    def transform(self, transf_matrix):
        self._points = transf_matrix.dot(np.vstack((self._points, np.ones(self.nbr_points()))))
Beispiel #3
0
def pyntcloud_and_eigenvalues():
    cloud = PyntCloud(pd.DataFrame(
        data={
            "x": np.array([0, 0, 1, -1, 0, 0], dtype=np.float32),
            "y": np.array([0, 1, 0, 0, -1, 0], dtype=np.float32),
            "z": np.array([0, 0, 0, 0, 0, 2], dtype=np.float32)
        }))

    k_neighbors = cloud.get_neighbors(k=4)

    ev = cloud.add_scalar_field("eigen_values", k_neighbors=k_neighbors)

    return cloud, ev
Beispiel #4
0
def computeNormals(model):
    cloudable = pd.DataFrame(data=np.transpose(model), columns=['x', 'y', 'z'])
    # calculates a pointcloud of the input model using a pandas DataFrame
    cloud = PyntCloud(cloudable)
    # use neighbors to get normals from pointcloud
    neighbors = cloud.get_neighbors(k=10)
    cloud.add_scalar_field('normals', k_neighbors=neighbors)
    # extract normals from the altered DataFrame
    normals = np.transpose(np.asarray(cloudable.loc[:, 'nx(10)':'nz(10)']))
    master = np.repeat(masterOrig, len(normals[0]), axis=1)
    # taking the dot product column-wise; the 'ij,ij->' notation is saying:
    # take dot product of ith row, jth column of normals and ith row, jth column of master
    # then, create boolean mask array for normal comparison
    I = np.einsum('ij,ij->j', normals, master) < 0
    # flip all values in column if I is true at that column (dot prod < 0)
    normals[:, I] = -normals[:, I]

    return (normals)