Пример #1
0
def explore_verticality_coef(fixture, draw, bins, size=SIZE):
    """

    Parameters
    ----------
    fixture : str
        Name of the fixture, amongst 'line', 'plane', 'sphere', 'ztube', 'wall'
    or 'roof'
    draw : int
        Number of random point cloud draws
    bins : numpy.array
        Returned histogram categories
    size : int
        Number of points in the point cloud

    Returns
    -------
    numpy.array
        Distribution of the verticality coefficient metric over a sample of
    point cloud
    """
    verticality_coef_list = []
    for d in range(draw):
        data = select_fixture(fixture, size)
        pca = PCA().fit(data)
        verticality_coef_list.append(features.verticality_coefficient(pca))
    return np.histogram(verticality_coef_list, bins=bins)
Пример #2
0
def test_verticality_coefficient_roof(roof):
    """Test verticality coefficient for a sphere-shaped point cloud

    As the point cloud is not constrained over x-, y- or z- axis, the
    verticality coefficient may take any value between 0 and 1. The test scope
    is limited to the definition domain.
    """
    pca = PCA().fit(roof)
    vcoef = verticality_coefficient(pca)
    assert vcoef >= 0 and vcoef <= 0.01
Пример #3
0
def test_verticality_coefficient_plane(plane):
    """Test verticality coefficient for a plane-shaped point cloud

    As data are spread over x and y-axis, the two first eigenvectors are
    supposed to have small z-components, hence the third eigenvector has a high
    z-component. So the verticality coefficient must be small (let say, smaller
    than 0.01).
    """
    pca = PCA().fit(plane)
    vcoef = verticality_coefficient(pca)
    assert vcoef >= 0 and vcoef < 0.01
Пример #4
0
def test_verticality_coefficient_line(line):
    """Test verticality coefficient for a line-shaped point cloud

    As the point cloud is constrained only over the x-axis, the first
    eigenvector is strongly influenced by the x-components. However the other
    eigenvectors may have any shape, hence the verticality coefficient may take
    any value between 0 and 1. The test scope is limited to the definition
    domain.
    """
    pca = PCA().fit(line)
    vcoef = verticality_coefficient(pca)
    assert vcoef >= 0 and vcoef <= 1
Пример #5
0
def test_3D_properties_plane_and_sphere_comparison(plane, sphere):
    """Compare all 3D properties between a sphere and a plane.

    """
    index = 42
    reference_point_plane = plane[index]
    reference_point_sphere = sphere[index]
    dist_plane, neighbors_plane = _neighbors(plane, reference_point_plane)
    dist_sphere, neighbors_sphere = _neighbors(sphere, reference_point_sphere)
    radius_plane = radius_3D(dist_plane)
    radius_sphere = radius_3D(dist_sphere)
    assert radius_sphere > radius_plane
    density_plane = density_3D(radius_plane, len(neighbors_plane))
    density_sphere = density_3D(radius_sphere, len(neighbors_sphere))
    assert density_plane > density_sphere
    z_range_plane = val_range(plane[neighbors_plane, 2])
    z_range_sphere = val_range(sphere[neighbors_sphere, 2])
    assert z_range_sphere > z_range_plane
    std_deviation_plane = std_deviation(plane[neighbors_plane, 2])
    std_deviation_sphere = std_deviation(sphere[neighbors_sphere, 2])
    assert std_deviation_sphere > std_deviation_plane
    vcoef_plane = verticality_coefficient(PCA().fit(plane))
    vcoef_sphere = verticality_coefficient(PCA().fit(sphere))
    assert vcoef_plane < vcoef_sphere
Пример #6
0
def process_full(neighbors, dist_to_neighbors, extra):
    """Build the full feature set for a single point

    Parameters
    ----------
    neighbors : numpy.array
        Coordinates of all points within the point neighborhood; must be a
    2D-shaped array with `point_cloud.shape[1] == 3`
    dist_to_neighbors : numpy.array
        Gives distance between the point and all its neighbors
    extra : ExtraFeatures
        Names and values of extra input features, e.g. the RGB color

    Returns
    ------
    list, OrderedDict generator (features for each point)

    """
    num_neighbors = neighbors.shape[0] - 1
    x, y, z = neighbors[0]
    rad_2D = radius_2D(neighbors[0, :2], neighbors[:, :2])
    rad_3D = radius_3D(dist_to_neighbors)
    if len(neighbors) <= 2:
        return (
            FeatureTuple(
                x, y, z,
                np.nan, np.nan,  # alpha, beta
                rad_3D,
                val_range(neighbors[:, 2]),  # z_range
                std_deviation(neighbors[:, 2]),  # std_dev
                density_3D(rad_3D, len(neighbors)),
                np.nan, np.nan, np.nan, np.nan, np.nan,
                np.nan, np.nan, np.nan, np.nan,
                rad_2D,
                density_2D(rad_2D, len(neighbors)),
                np.nan,  # eigenvalue_sum_2D
                np.nan,  # eigenvalue_ratio_2D
            ),
            extra
        )
    else:
        pca = fit_pca(neighbors)  # PCA on the x,y,z coords
        eigenvalues_3D = pca.singular_values_ ** 2
        norm_eigenvalues_3D = sum_normalize(eigenvalues_3D)
        alpha, beta = triangle_variance_space(norm_eigenvalues_3D)
        pca_2d = fit_pca(neighbors[:, :2])  # PCA just on the x,y coords
        eigenvalues_2D = pca_2d.singular_values_ ** 2
        return (
            FeatureTuple(
                x, y, z,
                num_neighbors,
                alpha, beta,
                rad_3D,
                val_range(neighbors[:, 2]),  # z_range
                std_deviation(neighbors[:, 2]),  # std_dev
                density_3D(rad_3D, len(neighbors)),
                verticality_coefficient(pca),
                curvature_change(norm_eigenvalues_3D),
                linearity(norm_eigenvalues_3D),
                planarity(norm_eigenvalues_3D),
                scattering(norm_eigenvalues_3D),
                omnivariance(norm_eigenvalues_3D),
                anisotropy(norm_eigenvalues_3D),
                eigenentropy(norm_eigenvalues_3D),
                val_sum(eigenvalues_3D),  # eigenvalue sum
                rad_2D,
                density_2D(rad_2D, len(neighbors)),
                val_sum(eigenvalues_2D),  # eigenvalue_sum_2D
                eigenvalue_ratio_2D(eigenvalues_2D)
            ),
            extra
        )