Esempio n. 1
0
    def extract_training(self, path):
        """
        This method extract features/labels of a subset of the training points. It ensures a balanced choice between
        classes.
        :param path: path where the ply files are located.
        :return: features and labels
        """

        # Get all the ply files in data folder
        ply_files = [f for f in listdir(path) if f.endswith('.ply')]

        # Initiate arrays
        training_features = np.empty((0, 12))
        training_labels = np.empty((0,))

        # Loop over each training cloud
        for i, file in enumerate(ply_files):

            # Load Training cloud
            cloud_ply = read_ply(join(path, file))
            points = np.vstack((cloud_ply['x'], cloud_ply['y'], cloud_ply['z'])).T
            labels = cloud_ply['class']

            # Initiate training indices array
            training_inds = np.empty(0, dtype=np.int32)

            # Loop over each class to choose training points
            for label, name in self.label_names.items():

                # Do not include class 0 in training
                if label == 0:
                    continue

                # Collect all indices of the current class
                label_inds = np.where(labels == label)[0]

                # If you have not enough indices, just take all of them
                if len(label_inds) <= self.num_per_class:
                    training_inds = np.hstack((training_inds, label_inds))

                # If you have more than enough indices, choose randomly
                else:
                    random_choice = np.random.choice(len(label_inds), self.num_per_class, replace=False)
                    training_inds = np.hstack((training_inds, label_inds[random_choice]))

            # Gather chosen points
            training_points = points[training_inds, :]

            # Compute features for the points of the chosen indices and place them in a [N, 4] matrix
            vert, line, plan, sphe = compute_features(training_points, points, self.radius)
            cosn, sinn, cost, sint, omnivariance, anisotropy, eigenentropy, change_curvature = compute_add_features(training_points, points, self.radius)
            features = np.vstack((vert.ravel(), line.ravel(), plan.ravel(), sphe.ravel(), cosn.ravel(), sinn.ravel(), cost.ravel(), sint.ravel(), omnivariance.ravel(), anisotropy.ravel(), eigenentropy.ravel(), change_curvature.ravel())).T

            # Concatenate features / labels of all clouds
            training_features = np.vstack((training_features, features))
            training_labels = np.hstack((training_labels, labels[training_inds]))

        return training_features, training_labels
Esempio n. 2
0
def basic_point_choice(num_per_class, radius, label_names):

    # Initiate arrays
    training_features = np.empty((0, 4))
    training_labels = np.empty((0, ))

    # Loop over each training cloud
    for i in range(1, 4):

        # Load Training cloud
        cloud_path = '../data/Lille_street_{:d}.ply'.format(i)
        cloud_ply = read_ply(cloud_path)
        points = np.vstack((cloud_ply['x'], cloud_ply['y'], cloud_ply['z'])).T
        labels = cloud_ply['labels']

        # Initiate training indices array
        training_inds = np.empty(0, dtype=np.int32)

        # Loop over each class to choose training points
        for label, name in label_names.items():

            # Do not include class 0 in training
            if label == 0:
                continue

            # Collect all indices of the current class
            label_inds = np.where(labels == label)[0]

            # If you have not enough indices, just take all of them
            if len(label_inds) <= num_per_class:
                training_inds = np.hstack((training_inds, label_inds))

            # If you have more than enough indices, choose randomly
            else:
                random_choice = np.random.choice(len(label_inds),
                                                 num_per_class,
                                                 replace=False)
                training_inds = np.hstack(
                    (training_inds, label_inds[random_choice]))

        # Compute features for the points of the chosen indices
        verticality, linearity, planarity, sphericity = compute_features(
            points[training_inds, :], points, radius)
        features = np.vstack((verticality.ravel(), linearity.ravel(),
                              planarity.ravel(), sphericity.ravel())).T

        # Concatenate features / labels of all clouds
        training_features = np.vstack((training_features, features))
        training_labels = np.hstack((training_labels, labels[training_inds]))

    return training_features, training_labels
Esempio n. 3
0
    def extract_test(self, path):
        """
        This method extract features of all the test points.
        :param path: path where the ply files are located.
        :return: features
        """

        # Get all the ply files in data folder
        ply_files = [f for f in listdir(path) if f.endswith('.ply')]

        # Initiate arrays
        test_features = np.empty((0, 4))

        # Loop over each training cloud
        for i, file in enumerate(ply_files):
            print("File {}: {}".format(i, file))

            # Load Training cloud
            cloud_ply = read_ply(join(path, file))
            points = np.vstack(
                (cloud_ply['x'], cloud_ply['y'], cloud_ply['z'])).T

            # Compute features only one time and save them for further use
            #
            #   WARNING : This will save you some time but do not forget to delete your features file if you change
            #             your features. Otherwise you will not compute them and use the previous ones
            #

            # Name the feature file after the ply file.
            feature_file = file[:-4] + '_features.npy'
            feature_file = join(path, feature_file)

            # If the file exists load the previously computed features
            if exists(join(path, feature_file)):
                features = np.load(feature_file)

            # If the file does not exist, compute the features (very long) and save them for future use
            else:

                vert, line, plan, sphe = compute_features(
                    points, points, self.radius)
                features = np.vstack(
                    (vert.ravel(), line.ravel(), plan.ravel(), sphe.ravel())).T
                np.save(feature_file, features)

            # Concatenate features of several clouds
            # (For this minichallenge this is useless as the test set contains only one cloud)
            test_features = np.vstack((test_features, features))

        return test_features
Esempio n. 4
0
def basic_training_and_test():

    # Parameters
    # **********
    #

    radius = 0.5
    num_per_class = 500
    label_names = {
        0: 'Unclassified',
        1: 'Ground',
        2: 'Building',
        3: 'Vegetation',
        4: 'Barriers',
        5: 'Cars',
        6: 'Signage'
    }

    # Collect training features / labels
    # **********************************
    #

    print('Collect Training Features')
    t0 = time.time()

    training_features, training_labels = basic_point_choice(
        num_per_class, radius, label_names)

    t1 = time.time()
    print('Done in %.3fs\n' % (t1 - t0))

    # Train a random forest classifier
    # ********************************
    #

    print('Training Random Forest')
    t0 = time.time()

    clf = RandomForestClassifier()
    clf.fit(training_features, training_labels)

    t1 = time.time()
    print('Done in %.3fs\n' % (t1 - t0))

    # Test
    # ****
    #

    print('Compute testing features')
    t0 = time.time()

    # Load cloud as a [N x 3] matrix
    cloud_path = '../data/Lille_street_test.ply'
    cloud_ply = read_ply(cloud_path)
    points = np.vstack((cloud_ply['x'], cloud_ply['y'], cloud_ply['z'])).T

    # Compute features only one time and save them for further use
    #
    #   WARNING : This will save you some time but do not forget to delete your features file if you change
    #             your features. Otherwise you will not compute them and use the previous ones
    #
    feature_file = '../data/Lille_street_test_features.npy'
    if exists(feature_file):
        features = np.load(feature_file)
    else:
        verticality, linearity, planarity, sphericity = compute_features(
            points, points, radius)
        features = np.vstack((verticality.ravel(), linearity.ravel(),
                              planarity.ravel(), sphericity.ravel())).T
        np.save(feature_file, features)

    t1 = time.time()
    print('Done in %.3fs\n' % (t1 - t0))

    print('Test')
    t0 = time.time()
    predictions = clf.predict(features)
    t1 = time.time()
    print('Done in %.3fs\n' % (t1 - t0))

    print('Save predictions')
    t0 = time.time()
    np.savetxt('../data/Lille_street_test_preds.txt', predictions, fmt='%d')
    t1 = time.time()
    print('Done in %.3fs\n' % (t1 - t0))

    print('Save predictions ply')
    t0 = time.time()
    write_ply('../Lille_street_test_preds.ply', [points, predictions],
              ['x', 'y', 'z', 'labels'])
    t1 = time.time()
    print('Done in %.3fs\n' % (t1 - t0))