コード例 #1
0
def compute_cell_neighborhood(environment_pc, target_pc, side_length):
    """
    Find the indices of points within a square neighbourhood for a given point of a target point cloud among the
    points from an environment point cloud.

    :param environment_pc: environment point cloud
    :param target_pc: point cloud that contains the points at which neighborhoods are to be calculated
    :param side_length: search radius for neighbors
    :return: indices of neighboring points from the environment point cloud for each target point
    """

    max_radius = 0.5 * math.sqrt((side_length**2) + (side_length**2))

    neighbors = compute_cylinder_neighborhood(environment_pc, target_pc,
                                              max_radius)

    counter = 0  # Target and neighborhood indices are going to be out of sync in loop below.
    for neighborhood_indices in neighbors:
        result = []
        for i, _ in enumerate(neighborhood_indices):
            target_x, target_y, _ = utils.get_point(target_pc, counter)
            counter += 1
            neighbor_indices = neighborhood_indices[i]
            result_indices = []
            for j in neighbor_indices:
                env_x, env_y, _ = utils.get_point(environment_pc, j)
                if ((abs(target_x - env_x)) > 0.5 * side_length) or (
                    (abs(target_y - env_y)) > 0.5 * side_length):
                    continue
                else:
                    result_indices.append(j)
            result.append(result_indices)
        yield result
コード例 #2
0
def compute_cube_neighborhood(environment_pc, target_pc, side_length):
    """
    Find the indices of points within a square neighbourhood for a given point of a target point cloud among the
    points from an environment point cloud.

    :param environment_pc: environment point cloud
    :param target_pc: point cloud that contains the points at which neighborhoods are to be calculated
    :param side_length: search radius for neighbors
    :return: indices of neighboring points from the environment point cloud for each target point
    """

    neighbors = compute_cell_neighborhood(environment_pc, target_pc,
                                          side_length)

    counter = 0
    for neighborhood_indices in neighbors:
        result = []
        for i, _ in enumerate(neighborhood_indices):
            _, _, target_z = utils.get_point(target_pc, counter)
            counter += 1
            neighbor_indices = neighborhood_indices[i]
            result_indices = []
            for j in neighbor_indices:
                _, _, env_z = utils.get_point(environment_pc, j)
                if abs(target_z - env_z) > side_length:
                    continue
                else:
                    result_indices.append(j)
            result.append(result_indices)
        yield result
コード例 #3
0
def compute_sphere_neighborhood(environment_pc, target_pc, radius):
    """
    Find the indices of points within a spherical neighbourhood for a given point of a target point cloud among the
    points from an environment point cloud.

    :param environment_pc: environment point cloud
    :param target_pc: point cloud that contains the points at which neighborhoods are to be calculated
    :param radius: search radius for neighbors
    :return: indices of neighboring points from the environment point cloud for each target point
    """
    neighborhoods = compute_cylinder_neighborhood(environment_pc, target_pc,
                                                  radius)

    counter = 0  # Target and neighborhood indices are going to be out of sync in loop below.
    for neighborhood_indices in neighborhoods:
        result = []
        for i, _ in enumerate(neighborhood_indices):
            target_x, target_y, target_z = utils.get_point(target_pc, counter)
            counter += 1
            result_indices = []
            for j in neighborhood_indices[i]:
                env_x, env_y, env_z = utils.get_point(environment_pc, j)
                if abs(target_z - env_z) > radius:
                    continue
                if (env_x - target_x)**2 + (env_y - target_y)**2 + (
                        env_z - target_z)**2 <= radius**2:
                    result_indices.append(j)
            result.append(result_indices)
        yield result
コード例 #4
0
 def test_GetPointCloudPoint(self):
     """ Should not raise exception. """
     pc = test_tools.generate_tiny_test_point_cloud()
     x, y, z = utils.get_point(pc, 1)
     self.assertEqual(2, x)
     self.assertEqual(3, y)
     self.assertEqual(4, z)
コード例 #5
0
    def extract(self, point_cloud, neighborhoods, target_point_cloud,
                target_index, volume_description):
        """
        Extract the feature value(s) of the point cloud at location of the target.

        :param point_cloud: environment (search space) point cloud
        :param neighborhoods: array of array of indices of points within the point_cloud argument
        :param target_point_cloud: point cloud that contains target point
        :param target_index: index of the target point in the target point cloud
        :param volume_description: volume object that describes the shape and size of the search volume
        :return: feature value
        """
        if volume_description.TYPE != 'infinite cylinder':
            raise ValueError('The volume must be a cylinder')

        if target_point_cloud is None:
            raise ValueError('Target point cloud required')

        if target_index is None:
            raise ValueError('Target point index required')

        # xyz = self.get_neighborhood_positions(point_cloud, neighborhood)
        xyz = get_xyz_per_neighborhood(point_cloud, neighborhoods)
        n_cylinder = np.sum(xyz.mask[:, 0, :] == False, axis=1, dtype=float)

        x0, y0, z0 = get_point(target_point_cloud, target_index)
        xyz0 = np.column_stack((x0, y0, z0))

        difference = xyz - xyz0[:, :, None]
        sum_of_squares = np.sum(difference**2, 1)
        n_sphere = np.sum(sum_of_squares <= volume_description.radius**2,
                          axis=1)
        return n_sphere / n_cylinder
コード例 #6
0
 def _get_random_targets(self):
     """Get a random target pc."""
     num_all_pc_points = len(self.point_cloud[keys.point]["x"]["data"])
     rand_indices = [
         random.randint(0, num_all_pc_points) for p in range(20)
     ]
     x, y, z = utils.get_point(self.point_cloud, rand_indices)
     return create_point_cloud(x, y, z)
コード例 #7
0
 def test_GetPointCloudPointFeature(self):
     """ Should not raise exception. """
     pc = test_tools.generate_tiny_test_point_cloud()
     cols = 0.5 * (pc[keys.point]["x"]["data"] +
                   pc[keys.point]["y"]["data"])
     pc[keys.point]["color"] = {"type": "double", "data": cols}
     x, y, z = utils.get_point(pc, 1)
     c = utils.get_attribute_value(pc, 1, "color")
     self.assertEqual(c, 0.5 * (x + y))
コード例 #8
0
 def _assert_all_points_within_sphere(self, index_sets, target_point_cloud,
                                      radius):
     point_clouds = [
         utils.copy_point_cloud(self.point_cloud, indices)
         for indices in index_sets
     ]
     n_targets = len(target_point_cloud[keys.point]["x"]["data"])
     assert_equal(n_targets, len(point_clouds))
     for i in range(n_targets):
         target_x, target_y, target_z = utils.get_point(
             target_point_cloud, i)
         for j in range(len(point_clouds[i][keys.point]["x"]["data"])):
             neighbor_x, neighbor_y, neighbor_z = utils.get_point(
                 point_clouds[i], j)
             dist = np.sqrt((neighbor_x - target_x)**2 +
                            (neighbor_y - target_y)**2 +
                            (neighbor_z - target_z)**2)
             self.assertTrue(dist <= radius)
コード例 #9
0
def compute_sphere_neighborhood(environment_pc, target_pc, radius):
    """
    Find the indices of points within a spherical neighbourhood for a given point of a target point cloud among the
    points from an environment point cloud.

    :param environment_pc: environment point cloud
    :param target_pc: point cloud that contains the points at which neighborhoods are to be calculated
    :param radius: search radius for neighbors
    :return: indices of neighboring points from the environment point cloud for each target point
    """
    neighborhoods = compute_cylinder_neighborhood(environment_pc, target_pc, radius)
    for target_i, neighborhood_indices in enumerate(neighborhoods):
        target_x, target_y, target_z = utils.get_point(target_pc, target_i)
        result_indices = []
        for neighbor_j in neighborhood_indices:
            env_x, env_y, env_z = utils.get_point(environment_pc, neighbor_j)
            if abs(target_z - env_z) > radius:
                continue
            if (env_x - target_x) ** 2 + (env_y - target_y) ** 2 + (env_z - target_z) ** 2 <= radius ** 2:
                result_indices.append(neighbor_j)
        yield result_indices
コード例 #10
0
    def extract(self, sourcepc, neighborhood, targetpc, targetindex, volume):
        nbptsX, nbptsY, nbptsZ = utils.get_point(sourcepc, neighborhood)
        matrix = np.column_stack((nbptsX, nbptsY, nbptsZ))

        try:
            eigenvals, eigenvecs = self._structure_tensor(matrix)
        except ValueError as err:
            if str(err) == 'Not enough points to compute eigenvalues/vectors.':
                return [0, 0, 0]
            else:
                raise

        return [eigenvals[0], eigenvals[1], eigenvals[2]]
コード例 #11
0
 def test_GetPointCloudPointFeatures(self):
     """ Should not raise exception. """
     pc = test_tools.generate_tiny_test_point_cloud()
     cols = 0.5 * (pc[keys.point]["x"]["data"] +
                   pc[keys.point]["y"]["data"])
     flavs = 0.5 * (pc[keys.point]["x"]["data"] -
                    pc[keys.point]["y"]["data"])
     pc[keys.point]["color"] = {"type": "double", "data": cols}
     pc[keys.point]["flavor"] = {"type": "double", "data": flavs}
     x, y, z = utils.get_point(pc, 2)
     c, f = utils.get_features(pc, ("color", "flavor"), 2)
     self.assertEqual(c, 0.5 * (x + y))
     self.assertEqual(f, 0.5 * (x - y))
コード例 #12
0
    def generate_targets(self,
                         min_x,
                         min_y,
                         max_x,
                         max_y,
                         n_tiles_side,
                         tile_mesh_size,
                         validate=True,
                         validate_precision=None):
        """
        Generate the target point cloud.

        :param min_x: Min x value of the tiling schema
        :param min_y: Min y value of the tiling schema
        :param max_x: Max x value of the tiling schema
        :param max_y: Max y value of the tiling schema
        :param n_tiles_side: Number of tiles along X and Y (tiling MUST be
        square)
        :param tile_mesh_size: Spacing between target points (in m). The tiles'
        width must be an integer times this spacing
        :param validate: If True, check if all points in the point-cloud belong
        to the same tile
        :param validate_precision: Optional precision threshold to determine
        whether point belong to tile
        """
        logger.info('Setting up the target grid')
        self.grid.setup(min_x, min_y, max_x, max_y, n_tiles_side)

        if any([idx is None for idx in self._tile_index]):
            raise RuntimeError('Tile index not set!')

        if validate:
            logger.info('Checking whether points belong to cell '
                        '({},{})'.format(*self._tile_index))
            x_all, y_all, _ = get_point(self.point_cloud, ...)
            mask = self.grid.is_point_in_tile(x_all, y_all,
                                              self._tile_index[0],
                                              self._tile_index[1],
                                              validate_precision)
            assert np.all(mask), ('{} points belong to (a) different tile(s)'
                                  '!'.format(len(x_all[~mask])))

        logger.info('Generating target point mesh with '
                    '{}m spacing '.format(tile_mesh_size))
        x_trgts, y_trgts = self.grid.generate_tile_mesh(
            self._tile_index[0], self._tile_index[1], tile_mesh_size)
        self.targets = create_point_cloud(x_trgts, y_trgts,
                                          np.zeros_like(x_trgts))
        return self
コード例 #13
0
    def _extract_one(source_point_cloud, neighborhood):
        """
        Extract the feature value(s) of the point cloud at location of the target.

        :param source_point_cloud: environment (search space) point cloud
        :param neighborhood: array of indices of points within the point_cloud argument
        :return:
        """
        x, y, z = get_point(source_point_cloud, neighborhood)
        try:
            plane_estimator = fit_plane(x, y, z)
            normalized = z - plane_estimator(x, y)
            return np.std(normalized)
        except LinAlgError:
            return 0
コード例 #14
0
    def extract(self, source_point_cloud, neighborhood, target_point_cloud, target_index, volume_description):
        """
        Extract the feature value(s) of the point cloud at location of the target.

        :param source_point_cloud: environment (search space) point cloud
        :param neighborhood: array of indices of points within the point_cloud argument
        :param target_point_cloud: point cloud that contains target point
        :param target_index: index of the target point in the target point cloud
        :param volume_description: volume object describing the containing volume of the neighborhood
        :return:
        """
        x, y, z = get_point(source_point_cloud, neighborhood)
        try:
            plane_estimator = fit_plane(x, y, z)
            normalized = z - plane_estimator(x, y)
            return np.std(normalized)
        except LinAlgError:
            return 0
コード例 #15
0
 def extract(self, sourcepc, neighborhood, targetpc, targetindex, volume):
     t2a, t2c = utils.get_features(targetpc, self.requires(), targetindex)
     x, y, z = utils.get_point(targetpc, targetindex)
     return t2c - t2a - z  # z
コード例 #16
0
 def extract(self, sourcepc, neighborhood, targetpc, targetindex, volume):
     t1b = utils.get_attribute_value(targetpc, targetindex,
                                     self.requires()[0])
     x, y, z = utils.get_point(targetpc, targetindex)
     return [x + t1b, y + t1b, z + t1b]  # x + 3z/2, y + 3z/2, 5z/2
コード例 #17
0
 def extract(self, sourcepc, neighborhood, targetpc, targetindex, volume):
     x, y, z = utils.get_point(targetpc, targetindex)
     return [0.5 * z, 1.5 * z]
コード例 #18
0
 def _extract_one(self, target_point_cloud, target_index):
     x, y, z = utils.get_point(target_point_cloud, target_index)
     return [0.5 * z, 1.5 * z]
コード例 #19
0
 def _extract_one(self, target_point_cloud, target_index):
     t1a, t2c = utils.get_features(target_point_cloud, self.requires(),
                                   target_index)
     x, y, z = utils.get_point(target_point_cloud, target_index)
     return t2c - t1a - z  # this should be: 2 z
コード例 #20
0
 def _extract_one(self, target_point_cloud, target_index):
     t1b = utils.get_attribute_value(target_point_cloud, target_index,
                                     self.requires()[0])
     x, y, z = utils.get_point(target_point_cloud, target_index)
     return [x + t1b, y + t1b, z + t1b]  # x + 3z/2, y + 3z/2, 5z/2