diff --git a/metrics/instance_segmentation_metrics.py b/metrics/instance_segmentation_metrics.py index 36a7eb34100b8b326b493cccdd2fc5a52ba1bcbd..33ff05a306be1fb1b57839af9ba2e1cfac6e8f14 100644 --- a/metrics/instance_segmentation_metrics.py +++ b/metrics/instance_segmentation_metrics.py @@ -271,16 +271,39 @@ class InstanceSegmentationMetrics: 'IoU': IoU, } metric_dict[str(label)] = tmp_dict + + # list of interesting metrics + interesting_parameters = ['true_positive', 'false_positive', 'false_negative', 'true_negative', 'precision', 'recall', 'f1_score', 'IoU'] + + # weight the metrics by tree hight + metric_dict_weighted_by_tree_hight = {} + # itialize the metric_dict_weighted_by_tree_hight + for parameter in interesting_parameters: + metric_dict_weighted_by_tree_hight[parameter] = 0 - # compute a singel f1 score weighted by the tree hight - f1_score_weighted = 0 for key, value in metric_dict.items(): - f1_score_weighted += value['f1_score'] * value['high_of_tree'] + for parameter in interesting_parameters: + metric_dict_weighted_by_tree_hight[parameter] += value[parameter] * value['high_of_tree'] + + # compute the metric_dict_weighted_by_tree_hight + for parameter in interesting_parameters: + metric_dict_weighted_by_tree_hight[parameter] = metric_dict_weighted_by_tree_hight[parameter] / sum([value['high_of_tree'] for key, value in metric_dict.items()]) + + # compute the mean of the metrics + metric_dict_mean = {} + for parameter in interesting_parameters: + metric_dict_mean[parameter] = 0 + + for key, value in metric_dict.items(): + for parameter in interesting_parameters: + metric_dict_mean[parameter] += value[parameter] + + # compute the metric_dict_mean + for parameter in interesting_parameters: + metric_dict_mean[parameter] = metric_dict_mean[parameter] / len(metric_dict) - # compute f1_score_weighted by dividing by the sum of the hights of the trees - f1_score_weighted = f1_score_weighted / sum([value['high_of_tree'] for key, value in metric_dict.items()]) - return metric_dict, f1_score_weighted + return metric_dict, metric_dict_weighted_by_tree_hight, metric_dict_mean def print_metrics(self, metric_dict): for key, value in metric_dict.items(): @@ -296,10 +319,11 @@ class InstanceSegmentationMetrics: def main(self): - metric_dict, f1_score_weighted = self.compute_metrics() + metric_dict, metric_dict_weighted_by_tree_hight, metric_dict_mean = self.compute_metrics() if self.verbose: - print(f'f1_score_weighted: {f1_score_weighted}') + f1_weighted_by_tree_hight = metric_dict_weighted_by_tree_hight['f1_score'] + print(f'f1_score_weighted: {f1_weighted_by_tree_hight}') for key, value in metric_dict.items(): print(f'Label: {key}, f1_score: {value["f1_score"]}, high_of_tree: {value["high_of_tree"]}') @@ -308,7 +332,7 @@ class InstanceSegmentationMetrics: if self.verbose: print(f'Metrics saved to {self.csv_file_name}') - return metric_dict, f1_score_weighted + return metric_dict, metric_dict_weighted_by_tree_hight, metric_dict_mean # main @@ -333,5 +357,5 @@ if __name__ == '__main__': ) # compute metrics - metric_dict = instance_segmentation_metrics.main() + metric_dict, _, _ = instance_segmentation_metrics.main() \ No newline at end of file diff --git a/metrics/instance_segmentation_metrics_in_folder.py b/metrics/instance_segmentation_metrics_in_folder.py index 4a7c610b91bb460168d54fb7d78a0dc6d6a81396..90fd881116e95ddb45ddbfcb410fa1d99f354543 100644 --- a/metrics/instance_segmentation_metrics_in_folder.py +++ b/metrics/instance_segmentation_metrics_in_folder.py @@ -85,7 +85,9 @@ class InstanceSegmentationMetricsInFolder(): raise Exception('Not all las files in the gt_las_folder_path and target_las_folder_path are matched') # run the instance segmentation metrics for each matched las file - f1_scores = [] + metric_dict_list = [] + f1_scores_weighted_list = [] + for gt_las_file_path, target_las_file_path in matched_paths: # get the core name of the gt_las_file_path @@ -122,12 +124,15 @@ class InstanceSegmentationMetricsInFolder(): csv_file_name=save_to_csv_path, verbose=self.verbose ) - _, f1_score_weighted = instance_segmentation_metrics.main() - f1_scores.append(f1_score_weighted) + metric_dict, metric_dict_weighted_by_tree_hight, metric_dict_mean = instance_segmentation_metrics.main() + f1_score_weighted = metric_dict_mean['f1_score'] + metric_dict_list.append(metric_dict.values()) #TODO: finish this + f1_scores_weighted_list.append(f1_score_weighted) - # calculate the mean f1 score - mean_f1_score = sum(f1_scores) / len(f1_scores) + # calculate the mean f1 score of weighted f1 scores + mean_f1_score = sum(f1_scores_weighted_list) / len(f1_scores_weighted_list) + if self.output_folder_path is not None: # create the output folder path save_to_csv_path = os.path.join(self.output_folder_path, 'mean_f1_score.csv') @@ -139,7 +144,6 @@ class InstanceSegmentationMetricsInFolder(): if self.verbose: print('Mean F1 Score: {}'.format(mean_f1_score)) - return mean_f1_score if __name__ == '__main__': diff --git a/optimization_pipeline/sem_seg.sh b/optimization_pipeline/sem_seg.sh new file mode 100755 index 0000000000000000000000000000000000000000..8f8d413ab0430f3797e6d5261fb275aeae1d085a --- /dev/null +++ b/optimization_pipeline/sem_seg.sh @@ -0,0 +1,173 @@ +#!/bin/bash + +############################ parameters ################################################# +# General parameters +CLEAR_INPUT_FOLDER=1 # 1: clear input folder, 0: not clear input folder +CONDA_ENV="pdal-env-1" # conda environment for running the pipeline + +# Tiling parameters +data_folder="" # path to the folder containing the data + +############################# end of parameters declaration ############################ + +# extract tiling parameters as command line arguments with the same default values +while getopts "d:n:s:h:t:g:l:m:o:p:" opt; do + case $opt in + d) data_folder="$OPTARG" + ;; + \?) echo "Invalid option -$OPTARG" >&2 + ;; + esac +done + +# print the letters to choose from in getopts +echo " The list of letters for the parameters:" +echo "d: data_folder" + +# print values of the parameters +echo " The values of the parameters:" +echo "data_folder: $data_folder" + +# Do the environment setup +# check if PYTHONPATH is set to the current directory +if [ -z "$PYTHONPATH" ]; then + echo "PYTHONPATH is not set. Setting it to the current directory" + export PYTHONPATH=$PWD +else + echo "PYTHONPATH is set to '$PYTHONPATH'" +fi + +# conda activate pdal-env-1 + +# check if activated conda environment is the same as the one specified in the parameters +if [ "$CONDA_DEFAULT_ENV" != "$CONDA_ENV" ]; then + echo "The activated conda environment is not the same as the one specified in the parameters." + echo "Please activate the correct conda environment and run the script again." + exit 1 +fi + +# if no input folder is provided, case a message and exit +if [ -z "$data_folder" ] +then + echo " " + echo "No input folder provided, please provide the input folder as a command line argument" + exit 1 +fi + +# clear input folder if CLEAR_INPUT_FOLDER is set to 1 +if [ $CLEAR_INPUT_FOLDER -eq 1 ] +then + # delete all the files and folders except the ply, las and laz files in the input folder + echo "Clearing input folder" + find $data_folder/ -type f ! -name '*.ply' ! -name '*.las' ! -name '*.laz' -delete # delete all the files except the ply and las files + find $data_folder/* -type d -exec rm -rf {} + # delete all the folders in the input folder + echo "Removed all the files and folders except the ply and las files in the input folder" +fi + +# check if there are las and laz files in the input folder +count_las=`ls -1 $data_folder/*.las 2>/dev/null | wc -l` +count_laz=`ls -1 $data_folder/*.laz 2>/dev/null | wc -l` + +count=$(($count_las + $count_laz)) + +if [ $count != 0 ]; then + echo "$count las files found in the input folder good to go with!" +else + echo "No las or laz files found in the input folder." + echo "All files in the input folder should have *.las or *.laz extension." + exit 1 +fi + +# do the conversion from laz to las if there are laz files in place (this is need for metrics calculation) +python nibio_preprocessing/convert_files_in_folder.py --input_folder $data_folder --output_folder $data_folder --out_file_type las --in_place --verbose + +# do the conversion to ply +python nibio_preprocessing/convert_files_in_folder.py --input_folder $data_folder --output_folder $data_folder --out_file_type ply --verbose + +# clear input folder if CLEAR_INPUT_FOLDER is set to 1 +if [ $CLEAR_INPUT_FOLDER -eq 1 ] +then + # delete all the files and folders except the ply and las files in the input folder + echo "Clearing input folder" + find $data_folder/ -type f ! -name '*.ply' ! -name '*.las' -delete # delete all the files except the ply and las files + find $data_folder/* -type d -exec rm -rf {} + # delete all the folders in the input folder + echo "Removed all the files and folders except the ply and las files in the input folder" +fi + +# move the output of the first step to the input folder of the second step +mkdir -p $data_folder/segmented_point_clouds + +# move all .segmented.ply files to the segmented_point_clouds folder if they are in the input folder +find $data_folder/ -type f -name '*.ply' -exec mv {} $data_folder/segmented_point_clouds/ \; + +# do the tiling and tile index generation +echo "Tiling and tile index generation" +python nibio_preprocessing/tiling.py \ +-i $data_folder/segmented_point_clouds/ \ +-o $data_folder/segmented_point_clouds/tiled \ +--tile_size 10 + +# remove small tiles using nibio_preprocessing/remove_small_tiles.py +for d in $data_folder/segmented_point_clouds/tiled/*; do + echo "Removing small tiles from $d" + python nibio_preprocessing/remove_small_tiles.py \ + --dir $d \ + --tile_index $d/tile_index.dat \ + --min_density 75 \ + --verbose +done + +# iterate over all the directories in the tiled folder +for d in $data_folder/segmented_point_clouds/tiled/*/; do + for f in $d/*.ply; do + echo "Processing $f file..." + python fsct/run.py \ + --model /home/nibio/mutable-outside-world/code/gitlab_fsct/instance_segmentation_classic/fsct/model/model.pth \ + --point-cloud $f \ + --batch_size 10 \ + --odir $d \ + --verbose \ + # --tile-index $d/tile_index.dat \ + # --buffer 2 + done +done + +# remove all the files in the tiled subfolders except the *segmented.ply and tile_index.dat files +find $data_folder/segmented_point_clouds/tiled/*/ -type f ! -name '*segmented.ply' ! -name 'tile_index.dat' -delete # delete all the files except the segmented.ply files +# delete all the folders in the tiled subfolders +find $data_folder/segmented_point_clouds/tiled/*/* -type d -exec rm -rf {} + + +# # merge the segmented point clouds +echo "Merging the segmented point clouds" +# iterate over all the directories in the tiled folder +for d in $data_folder/segmented_point_clouds/tiled/*/; do + # get a base name of the directory + base_name=$(basename $d) + # create a name for the merged file + merged_file_name=$data_folder/segmented_point_clouds/$base_name.segmented.ply + python nibio_preprocessing/merging_and_labeling.py \ + --data_folder $d \ + --output_file $merged_file_name \ + --only_merging +done + +# rename all the segmented.ply files to .ply in the tiled subfolders +for file in $data_folder/segmented_point_clouds/tiled/*/*; do + # skip if the file is not a ply file + if [[ $file != *.ply ]]; then + continue + fi + mv -- "$file" "${file%.segmented.ply}.ply" +done + +# rename all the folder in the tiled subfolders to .segmented suffix +for d in $data_folder/segmented_point_clouds/tiled/*; do + echo "Renaming $d to ${d%.segmented}" + # mv "$d" "${d%.segmented}" + mv $d{,.segmented} +done + + +# create folder for the output of the second step + +mkdir -p $data_folder/instance_segmented_point_clouds diff --git a/optimization_pipeline/tls.sh b/optimization_pipeline/tls.sh new file mode 100755 index 0000000000000000000000000000000000000000..996c1fd826cc19598ee5e7858f550eb06efa567b --- /dev/null +++ b/optimization_pipeline/tls.sh @@ -0,0 +1,224 @@ +#!/bin/bash + +############################ parameters ################################################# +# General parameters +CLEAR_INPUT_FOLDER=1 # 1: clear input folder, 0: not clear input folder +CONDA_ENV="pdal-env-1" # conda environment for running the pipeline + +# Tiling parameters +data_folder="" # path to the folder containing the data +N_TILES=3 +SLICE_THICKNESS=0.5 +FIND_STEMS_HEIGHT=1.5 +FIND_STEMS_THICKNESS=0.5 +GRAPH_MAXIMUM_CUMULATIVE_GAP=3 +ADD_LEAVES_VOXEL_LENGTH=0.5 +FIND_STEMS_MIN_POINTS=50 +GRAPH_EDGE_LENGTH=1.0 +ADD_LEAVES_EDGE_LENGTH=1.0 + +############################# end of parameters declaration ############################ + +# extract tiling parameters as command line arguments with the same default values +while getopts "d:n:s:h:t:g:l:m:o:p:" opt; do + case $opt in + d) data_folder="$OPTARG" + ;; + n) N_TILES="$OPTARG" + ;; + s) SLICE_THICKNESS="$OPTARG" + ;; + h) FIND_STEMS_HEIGHT="$OPTARG" + ;; + t) FIND_STEMS_THICKNESS="$OPTARG" + ;; + g) GRAPH_MAXIMUM_CUMULATIVE_GAP="$OPTARG" + ;; + l) ADD_LEAVES_VOXEL_LENGTH="$OPTARG" + ;; + m) FIND_STEMS_MIN_POINTS="$OPTARG" + ;; + o) GRAPH_EDGE_LENGTH="$OPTARG" + ;; + p) ADD_LEAVES_EDGE_LENGTH="$OPTARG" + ;; + \?) echo "Invalid option -$OPTARG" >&2 + ;; + esac +done + +# print the letters to choose from in getopts +echo " The list of letters for the parameters:" +echo "d: data_folder" +echo "n: N_TILES" +echo "s: SLICE_THICKNESS" +echo "h: FIND_STEMS_HEIGHT" +echo "t: FIND_STEMS_THICKNESS" +echo "g: GRAPH_MAXIMUM_CUMULATIVE_GAP" +echo "l: ADD_LEAVES_VOXEL_LENGTH" +echo "m: FIND_STEMS_MIN_POINTS" +echo "o: GRAPH_EDGE_LENGTH" +echo "p: ADD_LEAVES_EDGE_LENGTH" + +echo " " +# print values of the parameters +echo " The values of the parameters:" +echo "data_folder: $data_folder" +echo "N_TILES: $N_TILES" +echo "SLICE_THICKNESS: $SLICE_THICKNESS" +echo "FIND_STEMS_HEIGHT: $FIND_STEMS_HEIGHT" +echo "FIND_STEMS_THICKNESS: $FIND_STEMS_THICKNESS" +echo "GRAPH_MAXIMUM_CUMULATIVE_GAP: $GRAPH_MAXIMUM_CUMULATIVE_GAP" +echo "ADD_LEAVES_VOXEL_LENGTH: $ADD_LEAVES_VOXEL_LENGTH" +echo "FIND_STEMS_MIN_POINTS: $FIND_STEMS_MIN_POINTS" +echo "GRAPH_EDGE_LENGTH: $GRAPH_EDGE_LENGTH" +echo "ADD_LEAVES_EDGE_LENGTH: $ADD_LEAVES_EDGE_LENGTH" + +# exit 0 + +# Do the environment setup +# check if PYTHONPATH is set to the current directory +if [ -z "$PYTHONPATH" ]; then + echo "PYTHONPATH is not set. Setting it to the current directory" + export PYTHONPATH=$PWD +else + echo "PYTHONPATH is set to '$PYTHONPATH'" +fi + +# conda activate pdal-env-1 + +# check if activated conda environment is the same as the one specified in the parameters +if [ "$CONDA_DEFAULT_ENV" != "$CONDA_ENV" ]; then + echo "The activated conda environment is not the same as the one specified in the parameters." + echo "Please activate the correct conda environment and run the script again." + exit 1 +fi + +# if no input folder is provided, case a message and exit +if [ -z "$data_folder" ] +then + echo " " + echo "No input folder provided, please provide the input folder as a command line argument" + exit 1 +fi + +# Do the instances and iterate over all the segmented point clouds +for segmented_point_cloud in $data_folder/segmented_point_clouds/*.segmented.ply; do + # get the name of the segmented point cloud + segmented_point_cloud_name=$(basename $segmented_point_cloud) + # get the name of the segmented point cloud without the extension + segmented_point_cloud_name_no_ext="${segmented_point_cloud_name%.*}" + # create a directory for the instance segmented point clouds + mkdir -p $data_folder/instance_segmented_point_clouds/$segmented_point_cloud_name_no_ext + # iterate over all the tiles of the segmented point cloud + for tile in $data_folder/segmented_point_clouds/tiled/$segmented_point_cloud_name_no_ext/*.ply; do + # get the name of the tile + tile_name=$(basename $tile) + # get the name of the tile without the extension + tile_name_no_ext="${tile_name%.*}" + echo "Processing $tile" + # show the output folder + echo "Output folder: $data_folder/instance_segmented_point_clouds/$segmented_point_cloud_name_no_ext/$tile_name_no_ext" + python3 fsct/points2trees.py \ + -t $tile \ + --tindex $data_folder/segmented_point_clouds/tiled/$segmented_point_cloud_name_no_ext/tile_index.dat \ + -o $data_folder/instance_segmented_point_clouds/$segmented_point_cloud_name_no_ext/$tile_name_no_ext \ + --n-tiles $N_TILES \ + --slice-thickness $SLICE_THICKNESS \ + --find-stems-height $FIND_STEMS_HEIGHT \ + --find-stems-thickness $FIND_STEMS_THICKNESS \ + --pandarallel --verbose \ + --add-leaves \ + --add-leaves-voxel-length $ADD_LEAVES_VOXEL_LENGTH \ + --graph-maximum-cumulative-gap $GRAPH_MAXIMUM_CUMULATIVE_GAP \ + --save-diameter-class \ + --ignore-missing-tiles \ + --find-stems-min-points $FIND_STEMS_MIN_POINTS \ + --graph-edge-length $GRAPH_EDGE_LENGTH \ + --add-leaves-edge-length $ADD_LEAVES_EDGE_LENGTH + done +done + +# do merging of the instance segmented point clouds +for instance_segmented_point_cloud in $data_folder/instance_segmented_point_clouds/*; do + python nibio_preprocessing/merging_and_labeling.py \ + --data_folder $instance_segmented_point_cloud \ + --output_file $instance_segmented_point_cloud/output_instance_segmented.ply +done + +# create the results folder +mkdir -p $data_folder/results + +# # create the input data folder +mkdir -p $data_folder/results/input_data + +# # move input data (ply and las) to the input data folder +find $data_folder/ -maxdepth 1 -type f -name '*.ply' -exec mv {} $data_folder/results/input_data/ \; +find $data_folder/ -maxdepth 1 -type f -name '*.las' -exec mv {} $data_folder/results/input_data/ \; + +# # create the segmented point clouds folder +mkdir -p $data_folder/results/segmented_point_clouds + +# move segmented point clouds to the segmented point clouds folder +find $data_folder/segmented_point_clouds/ -maxdepth 1 -type f -name '*segmented.ply' -exec mv {} $data_folder/results/segmented_point_clouds/ \; + +# # create the instance segmented point clouds folder +mkdir -p $data_folder/results/instance_segmented_point_clouds + +# iterate over all the instance segmented point clouds +# move instance segmented point clouds to the instance segmented point clouds folder and rename them +for instance_segmented_point_cloud in $data_folder/instance_segmented_point_clouds/*; do + # get the name of the instance segmented point cloud + instance_segmented_point_cloud_name=$(basename $instance_segmented_point_cloud) + # get the name of the instance segmented point cloud without the extension and add the suffix instance_segmented + instance_segmented_point_cloud_name_no_ext="${instance_segmented_point_cloud_name%.*}.instance_segmented" + # move the instance segmented point cloud to the instance segmented point clouds folder + find $instance_segmented_point_cloud/ -maxdepth 1 -type f -name '*.ply' -exec mv {} $data_folder/results/instance_segmented_point_clouds/$instance_segmented_point_cloud_name_no_ext.ply \; + # map the instance segmented point cloud to las file + pdal translate \ + $data_folder/results/instance_segmented_point_clouds/$instance_segmented_point_cloud_name_no_ext.ply \ + $data_folder/results/instance_segmented_point_clouds/$instance_segmented_point_cloud_name_no_ext.las \ + --writers.las.dataformat_id=3 \ + --writers.las.extra_dims=all +done + + # change the names of the segmented files to *.segmented.las +for segmented_point_cloud_in_ply in $data_folder/results/segmented_point_clouds/*; do + # get the prefix of the point clouds + SEGMENTED_POINT_CLOUDS_PREFIX="segmented." + # get the ending of the point clouds + SEGMENTED_POINT_CLOUDS_EXTENSION="ply" + # get the name of the ply point cloud + segmented_point_cloud_in_ply_name=$(basename $segmented_point_cloud_in_ply) + # got the name of the las file without the starting prefix and the .ply extension + segmented_point_cloud_in_las_name_no_prefix_no_extension=${segmented_point_cloud_in_ply_name#$SEGMENTED_POINT_CLOUDS_PREFIX} + segmented_point_cloud_in_las_name_no_extension=${segmented_point_cloud_in_las_name_no_prefix_no_extension%.$SEGMENTED_POINT_CLOUDS_EXTENSION} + # convert it to las and move it to the segmented point clouds folder + pdal translate \ + $segmented_point_cloud_in_ply \ + $data_folder/results/segmented_point_clouds/$segmented_point_cloud_in_las_name_no_extension.las \ + --writers.las.dataformat_id=3 \ + --writers.las.extra_dims=all +done + +python nibio_preprocessing/add_ground_to_inst_seg_folders.py --sem_seg_folder sample_playground/results/segmented_point_clouds/ --inst_seg_folder sample_playground/results/instance_segmented_point_clouds/ --output_folder sample_playground/instance_seg_with_ground --verbose + +# create the instance segmented point clouds with ground folder +mkdir -p $data_folder/results/instance_segmented_point_clouds_with_ground + +# to add the ground to the instance segmented point clouds +python nibio_preprocessing/add_ground_to_inst_seg_folders.py \ +--sem_seg_folder $data_folder/results/segmented_point_clouds/ \ +--inst_seg_folder $data_folder/results/instance_segmented_point_clouds/ \ +--output_folder $data_folder/results/instance_segmented_point_clouds_with_ground \ +--verbose + +echo " " +echo "Done" +# print path to the results folder and the subfolders +echo "Results can be found here: $data_folder/results" +echo "Results containing the input point clouds can be found here: $data_folder/results/input_data" +echo "Results containing the segmented point clouds can be found here: $data_folder/results/segmented_point_clouds" +echo "Results containing the instance segmented point clouds can be found here: $data_folder/results/instance_segmented_point_clouds" +echo "Results containing the instance segmented point clouds with ground can be found here: $data_folder/results/instance_segmented_point_clouds_with_ground" + diff --git a/pipeline_test_command_params_just_tls.py b/pipeline_test_command_params_just_tls.py new file mode 100644 index 0000000000000000000000000000000000000000..5242fb987278809a3bfd3d54cfa32b963e4e3eed --- /dev/null +++ b/pipeline_test_command_params_just_tls.py @@ -0,0 +1,126 @@ +import subprocess + +import wandb +# local imports +from metrics.instance_segmentation_metrics_in_folder import \ + InstanceSegmentationMetricsInFolder + +# wandb.login() + +# wandb.init(project="instance_segmentation_classic", entity="smart_forest") + +# define a class to run the command with arguments +class RunCommand: + def __init__(self, cmd, args): + self.cmd = cmd + self.args = args + + def __call__(self): + print("Running command: " + self.cmd + " " + " ".join(self.args)) + subprocess.run([self.cmd, *self.args]) + +def main( + n_tiles, + slice_thickness, + find_stems_height, + find_stems_thickness, + graph_maximum_cumulative_gap, + add_leaves_voxel_length, + find_stems_min_points, + graph_edge_length, + add_leaves_edge_length + ): + + # initialize the sweep + run = wandb.init(project="paper-sweep-nibio-model-just-tls", entity="smart_forest") + + # get files for the sweep + print("Getting files for the sweep") + cmd = "/home/nibio/mutable-outside-world/code/gitlab_fsct/instance_segmentation_classic/bash_helper_scripts/get_terrestial_sem_seg_validation_after_sem_seg.sh" + subprocess.run([cmd], shell=True) + + # define the arguments for all the parameters from the sweep configuration + print("Defining arguments for all the parameters from the sweep configuration") + + # print the arguments + print("N_TILES: " + str(n_tiles)) + print("SLICE_THICKNESS: " + str(slice_thickness)) + print("FIND_STEMS_HEIGHT: " + str(find_stems_height)) + print("FIND_STEMS_THICKNESS: " + str(find_stems_thickness)) + print("GRAPH_MAXIMUM_CUMULATIVE_GAP: " + str(graph_maximum_cumulative_gap)) + print("ADD_LEAVES_VOXEL_LENGTH: " + str(add_leaves_voxel_length)) + print("FIND_STEMS_MIN_POINTS: " + str(find_stems_min_points)) + print("GRAPH_EDGE_LENGTH: " + str(graph_edge_length)) + print("ADD_LEAVES_EDGE_LENGTH: " + str(add_leaves_edge_length)) + + # define the command + cmd = "./optimization_pipeline/tls.sh" + + # define the arguments + args = [ + "-d", "/home/nibio/mutable-outside-world/code/gitlab_fsct/instance_segmentation_classic/sample_playground" + ] + + print("Adding the arguments to the list of arguments") + args.extend([ + "-n", str(n_tiles), + "-s", str(slice_thickness), + "-h", str(find_stems_height), + "-t", str(find_stems_thickness), + "-g", str(graph_maximum_cumulative_gap), + "-l", str(add_leaves_voxel_length), + "-m", str(find_stems_min_points), + "-o", str(graph_edge_length), + "-p", str(add_leaves_edge_length) + ]) + + # run the command with the arguments + print("Running the command with the arguments") + RunCommand(cmd, args)() + + # compute the metric + print("Computing the metric") + metric = InstanceSegmentationMetricsInFolder( + gt_las_folder_path = '/home/nibio/mutable-outside-world/code/gitlab_fsct/instance_segmentation_classic/sample_playground/results/input_data', + target_las_folder_path = '/home/nibio/mutable-outside-world/code/gitlab_fsct/instance_segmentation_classic/sample_playground/results/instance_segmented_point_clouds', + remove_ground=True, + verbose=True + ) + + f1_score = metric.main() + print("F1 score: " + str(f1_score)) + + # log the metric + print("Logging the metric") + wandb.log({"f1_score": f1_score}) + +if __name__ == "__main__": + # use argparse to get the arguments + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("--n_tiles", type=int, default=1) + parser.add_argument("--slice_thickness", type=float, default=0.1) + parser.add_argument("--find_stems_height", type=float, default=0.1) + parser.add_argument("--find_stems_thickness", type=float, default=0.1) + parser.add_argument("--graph_maximum_cumulative_gap", type=float, default=0.1) + parser.add_argument("--add_leaves_voxel_length", type=float, default=0.1) + parser.add_argument("--find_stems_min_points", type=int, default=1) + parser.add_argument("--graph_edge_length", type=float, default=0.1) + parser.add_argument("--add_leaves_edge_length", type=float, default=0.1) + args = parser.parse_args() + + # run the main function + main( + args.n_tiles, + args.slice_thickness, + args.find_stems_height, + args.find_stems_thickness, + args.graph_maximum_cumulative_gap, + args.add_leaves_voxel_length, + args.find_stems_min_points, + args.graph_edge_length, + args.add_leaves_edge_length + ) + + +