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
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
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
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))