From 8c96a2c4529ca722d6084d3aa028da93f6d95a9d Mon Sep 17 00:00:00 2001 From: Maciej Wielgosz <maciej.wielgosz@nibio.no> Date: Fri, 14 Oct 2022 08:53:26 +0200 Subject: [PATCH] remove small tiles --- nibio_preprocessing/remove_small_tiles.py | 52 ++++++++++++++++------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/nibio_preprocessing/remove_small_tiles.py b/nibio_preprocessing/remove_small_tiles.py index 999fe4c..17be4f1 100644 --- a/nibio_preprocessing/remove_small_tiles.py +++ b/nibio_preprocessing/remove_small_tiles.py @@ -5,13 +5,19 @@ import plyfile class RemoveSmallTiles(): + """ + Works with ply files. + """ def __init__(self, dir, min_density, tile_index_file, verbose=False): self.dir = dir self.min_size = min_density self.tile_index_file = tile_index_file self.verbose = verbose - def get_density_of_single_tile(self, tile_path): + def get_density_and_points_nr_of_single_tile(self, tile_path): + """ + Get the density of a single tile. + """ plydata = plyfile.PlyData.read(tile_path) volume = (plydata['vertex']['x'].max() - plydata['vertex']['x'].min()) \ * (plydata['vertex']['y'].max() - plydata['vertex']['y'].min()) \ @@ -20,7 +26,7 @@ class RemoveSmallTiles(): number_of_points = plydata['vertex'].count density = number_of_points / volume - return density + return density, number_of_points @staticmethod def remove_line_from_csv(path, line): @@ -35,49 +41,65 @@ class RemoveSmallTiles(): f.write(lines[i]) def get_density_of_all_tiles(self): - # read all the ply files in the folder + """ + Get the density of all tiles in the directory. + """ files = glob.glob(os.path.join(self.dir, "*.ply")) if self.verbose: print(f'Found {len(files)} tiles') # compute the density of each tile and put it in a dictionary toghehter with the file path - densities = {} + densities_and_point_nr = {} for i, ply in enumerate(files): # get a fine name without the path and suffix file_name = os.path.split(ply)[1].split('.')[0] # full path to the tile tile_path = os.path.join(self.dir, file_name + '.ply') # get the density of the tile - density = self.get_density_of_single_tile(ply) + density = self.get_density_and_points_nr_of_single_tile(ply) # put it into a tuple together with the file name - densities[i] = (file_name, tile_path, density) + densities_and_point_nr[i] = (file_name, tile_path, density[0], density[1]) if self.verbose: print(f'Computed density of all tiles') - return densities + return densities_and_point_nr + def remove_small_tiles(self): + """ + Remove tiles that are too small. + """ # get the density of all tiles - densities = self.get_density_of_all_tiles() + densities_and_point_nr = self.get_density_of_all_tiles() - # remove the tiles that are too small - for i, density in densities.items(): - if density[2] < self.min_size: + # remove the tiles that whicha are too small (points per m^3) + for i, density in densities_and_point_nr.items(): + if density[3] < 10000: if self.verbose: - print(f'Removing tile {density[0]} with density {density[2]}') + print(f'Removing {density[1]} which has only {density[3]} points') os.remove(density[1]) self.remove_line_from_csv(self.tile_index_file, i) + # remove the tiles that of a small density + for i, density in densities_and_point_nr.items(): + if density[2] < self.min_size: + if self.verbose: + print(f'Removing tile {density[0]} with density {density[2]}') + # check if the tile is already removed + if os.path.exists(density[1]): + os.remove(density[1]) + self.remove_line_from_csv(self.tile_index_file, i) + # if verbose print the lowest and the highest density along with the tile name if self.verbose: - print(f'Lowest density: {min(densities.values(), key=lambda x: x[2])}') - print(f'Highest density: {max(densities.values(), key=lambda x: x[2])}') + print(f'Lowest density: {min(densities_and_point_nr.values(), key=lambda x: x[2])}') + print(f'Highest density: {max(densities_and_point_nr.values(), key=lambda x: x[2])}') # if verbose print the number of tiles that were removed if self.verbose: - print(f'Removed {len(densities) - len(glob.glob(os.path.join(self.dir, "*.ply")))} tiles') + print(f'Removed {len(densities_and_point_nr) - len(glob.glob(os.path.join(self.dir, "*.ply")))} tiles') def main(self): self.remove_small_tiles() -- GitLab