From 7e9b05dc2749a688325aac58a8f55c816437b81a Mon Sep 17 00:00:00 2001 From: Nakshatra Date: Thu, 12 Dec 2024 16:27:52 +0530 Subject: [PATCH 1/4] updated for df usage --- src/deepforest/dataset.py | 6 +++++- src/deepforest/main.py | 12 +++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/deepforest/dataset.py b/src/deepforest/dataset.py index 1cc595ce..f0421465 100644 --- a/src/deepforest/dataset.py +++ b/src/deepforest/dataset.py @@ -66,7 +66,11 @@ def __init__(self, Returns: If train, path, image, targets else image """ - self.annotations = pd.read_csv(csv_file) + # Check if csv_file is a DataFrame or a file path + if isinstance(csv_file, pd.DataFrame): + self.annotations = csv_file + else: + self.annotations = pd.read_csv(csv_file) self.root_dir = root_dir if transforms is None: self.transform = get_transform(augment=train) diff --git a/src/deepforest/main.py b/src/deepforest/main.py index 320beca0..256744cb 100644 --- a/src/deepforest/main.py +++ b/src/deepforest/main.py @@ -431,7 +431,8 @@ def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1 Deprecation warning: The return_plot argument is deprecated and will be removed in 2.0. Use visualize.plot_results on the result instead. Args: - csv_file: path to csv file + (earlier) csv_file: path to csv file + csv_file (str or pd.DataFrame): Path to a CSV file or a DataFrame with annotations. root_dir: directory of images. If none, uses "image_dir" in config (deprecated) savedir: directory to save images with bounding boxes (deprecated) color: color of the bounding box as a tuple of BGR color, e.g. orange annotations is (0, 165, 255) @@ -441,11 +442,16 @@ def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1 df: pandas dataframe with bounding boxes, label and scores for each image in the csv file """ - df = utilities.read_file(csv_file) - ds = dataset.TreeDataset(csv_file=csv_file, + # Use DataFrame directly if provided, otherwise treat as file path + if isinstance(csv_file, pd.DataFrame): + df = csv_file + else: + df = utilities.read_file(csv_file) + ds = dataset.TreeDataset(csv_file=df, root_dir=root_dir, transforms=None, train=False) + dataloader = self.predict_dataloader(ds) results = predict._dataloader_wrapper_(model=self, From d82f3df75a375be17dbbb09c6e4bdef11c903d0b Mon Sep 17 00:00:00 2001 From: Nakshatra Date: Fri, 13 Dec 2024 23:30:50 +0530 Subject: [PATCH 2/4] Update main.py --- src/deepforest/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/deepforest/main.py b/src/deepforest/main.py index 256744cb..0d1ed1d6 100644 --- a/src/deepforest/main.py +++ b/src/deepforest/main.py @@ -431,7 +431,6 @@ def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1 Deprecation warning: The return_plot argument is deprecated and will be removed in 2.0. Use visualize.plot_results on the result instead. Args: - (earlier) csv_file: path to csv file csv_file (str or pd.DataFrame): Path to a CSV file or a DataFrame with annotations. root_dir: directory of images. If none, uses "image_dir" in config (deprecated) savedir: directory to save images with bounding boxes From 4361fca503ca48d1e90432f7884869059b59d47b Mon Sep 17 00:00:00 2001 From: Nakshatra Date: Tue, 24 Dec 2024 13:44:45 +0530 Subject: [PATCH 3/4] fixes main.predict_file for numeric labels --- src/deepforest/main.py | 7 ++++++- tests/test_main.py | 10 +++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/deepforest/main.py b/src/deepforest/main.py index 0d1ed1d6..429abaaf 100644 --- a/src/deepforest/main.py +++ b/src/deepforest/main.py @@ -420,7 +420,8 @@ def predict_image(self, result = utilities.read_file(result, root_dir=root_dir) return result - + + label_dict: dict = {"Tree": 0} def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1): """Create a dataset and predict entire annotation file Csv file format is .csv file with the columns "image_path", "xmin","ymin","xmax","ymax" @@ -446,6 +447,10 @@ def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1 df = csv_file else: df = utilities.read_file(csv_file) + + # Map cropmodel_label to string labels using label_dict + df['label'] = df['label'].map({v: k for k, v in self.label_dict.items()}) + ds = dataset.TreeDataset(csv_file=df, root_dir=root_dir, transforms=None, diff --git a/tests/test_main.py b/tests/test_main.py index a8c3543e..d573be43 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -650,7 +650,6 @@ def test_predict_tile_with_crop_model(m, config): "cropmodel_score", "image_path" } - def test_predict_tile_with_crop_model_empty(): """If the model return is empty, the crop model should return an empty dataframe""" raster_path = get_data("SOAP_061.png") @@ -659,9 +658,11 @@ def test_predict_tile_with_crop_model_empty(): patch_overlap = 0.05 iou_threshold = 0.15 mosaic = True - # Set up the crop model crop_model = model.CropModel() + # Configure the label dictionary + m.label_dict = {"Tree": 0, "Bush": 1} + # Call the predict_tile method with the crop_model m.config["train"]["fast_dev_run"] = False m.create_trainer() @@ -672,5 +673,8 @@ def test_predict_tile_with_crop_model_empty(): mosaic=mosaic, crop_model=crop_model) - # Assert the result + # If result is not None, map cropmodel_label to string + if result is not None and not result.empty: + result['cropmodel_label'] = result['cropmodel_label'].map({v: k for k, v in m.label_dict.items()}) + assert result is None From 09a24ef1e3a84a191e2aa87b22354b39e2a75a30 Mon Sep 17 00:00:00 2001 From: Nakshatra Date: Tue, 24 Dec 2024 13:49:29 +0530 Subject: [PATCH 4/4] removed changes accidentally committed to the wrong branch so removed it --- src/deepforest/main.py | 5 +---- tests/test_main.py | 13 ++++--------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/deepforest/main.py b/src/deepforest/main.py index 429abaaf..82ca4f9e 100644 --- a/src/deepforest/main.py +++ b/src/deepforest/main.py @@ -421,7 +421,7 @@ def predict_image(self, return result - label_dict: dict = {"Tree": 0} + def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1): """Create a dataset and predict entire annotation file Csv file format is .csv file with the columns "image_path", "xmin","ymin","xmax","ymax" @@ -448,9 +448,6 @@ def predict_file(self, csv_file, root_dir, savedir=None, color=None, thickness=1 else: df = utilities.read_file(csv_file) - # Map cropmodel_label to string labels using label_dict - df['label'] = df['label'].map({v: k for k, v in self.label_dict.items()}) - ds = dataset.TreeDataset(csv_file=df, root_dir=root_dir, transforms=None, diff --git a/tests/test_main.py b/tests/test_main.py index d573be43..f4019335 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -649,7 +649,7 @@ def test_predict_tile_with_crop_model(m, config): "xmin", "ymin", "xmax", "ymax", "label", "score", "cropmodel_label", "geometry", "cropmodel_score", "image_path" } - + def test_predict_tile_with_crop_model_empty(): """If the model return is empty, the crop model should return an empty dataframe""" raster_path = get_data("SOAP_061.png") @@ -658,11 +658,9 @@ def test_predict_tile_with_crop_model_empty(): patch_overlap = 0.05 iou_threshold = 0.15 mosaic = True + # Set up the crop model crop_model = model.CropModel() - # Configure the label dictionary - m.label_dict = {"Tree": 0, "Bush": 1} - # Call the predict_tile method with the crop_model m.config["train"]["fast_dev_run"] = False m.create_trainer() @@ -673,8 +671,5 @@ def test_predict_tile_with_crop_model_empty(): mosaic=mosaic, crop_model=crop_model) - # If result is not None, map cropmodel_label to string - if result is not None and not result.empty: - result['cropmodel_label'] = result['cropmodel_label'].map({v: k for k, v in m.label_dict.items()}) - - assert result is None + # Assert the result + assert result is None \ No newline at end of file