Skip to content

Commit 5196449

Browse files
committed
[ADD] logic and template for calculating area for each class in an image
1 parent 64b66e3 commit 5196449

1 file changed

Lines changed: 43 additions & 3 deletions

File tree

src/metrics.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import numpy as np
66
from PIL import Image
77

8-
from utils.extras import LABELS
8+
from utils.extras import LABELS, TITLE
99

1010

1111
def pixel_accuracy(pred, label, num_classes):
@@ -126,7 +126,41 @@ def evaluate_segmentation_metrics(pred_mask, gt_mask, num_classes):
126126
}
127127

128128

129-
def process_folders(pred_folder, gt_folder, num_classes=8, ignore_value=-1):
129+
def calculate_area_per_class(pred_mask, pred_file, num_classes, area_csv_path):
130+
"""
131+
Calculate the area per class in the predicted mask and save it to a CSV file.
132+
The CSV should have the following columns:
133+
- ID
134+
- Class
135+
- Area
136+
137+
Args:
138+
pred_mask (np.ndarray): The predicted mask
139+
image_id (str): The ID of the image
140+
num_classes (int): Number of classes in the dataset
141+
area_csv_path (str): Path to where the CSV file will be saved
142+
"""
143+
if pred_file.startswith("predmask_"):
144+
pred_file = pred_file.replace("predmask_", "", 1)
145+
146+
image_id = os.path.basename(pred_file).split(".")[0]
147+
148+
149+
if not os.path.exists(area_csv_path):
150+
with open(area_csv_path, "w") as f:
151+
f.write("ID,Class,Area\n")
152+
153+
# TODO: Find a better unit for the area, now its just based on the number of pixels
154+
for cls in range(num_classes):
155+
cls_mask = pred_mask == cls
156+
area = np.sum(cls_mask)
157+
with open(area_csv_path, "a") as f:
158+
f.write(f"{image_id},{cls},{area}\n")
159+
160+
161+
def process_folders(
162+
pred_folder, gt_folder, num_classes, area_csv_path, ignore_value=-1
163+
):
130164
metrics_list = []
131165

132166
pred_files = sorted(glob.glob(pred_folder + "/*.tif"))
@@ -139,6 +173,7 @@ def process_folders(pred_folder, gt_folder, num_classes=8, ignore_value=-1):
139173
pred_mask, gt_mask = apply_ignore_index(pred_mask, gt_mask, ignore_value)
140174

141175
metrics = evaluate_segmentation_metrics(pred_mask, gt_mask, num_classes)
176+
calculate_area_per_class(pred_mask, pred_file, num_classes, area_csv_path)
142177
metrics_list.append(metrics)
143178

144179
return metrics_list
@@ -190,12 +225,17 @@ def aggregate_metrics(metrics_list):
190225

191226
@hydra.main(version_base=None, config_path="../configs", config_name="config")
192227
def main(cfg):
228+
print(TITLE)
193229
pred_folder = cfg.paths.PRED_TEST_MASKS
194230
gt_folder = cfg.paths.GT_TEST_MASKS
195231
num_classes = cfg.train.NUM_CLASSES
232+
area_csv_path = cfg.paths.AREA_CSV_PATH
196233
ignore_value = -1
197234

198-
metrics_list = process_folders(pred_folder, gt_folder, num_classes, ignore_value)
235+
metrics_list = process_folders(
236+
pred_folder, gt_folder, num_classes, area_csv_path, ignore_value
237+
)
238+
print(f"Area per class for all images saved to {area_csv_path}")
199239
avg_metrics = aggregate_metrics(metrics_list)
200240

201241
print("Average Metrics for all masks:")

0 commit comments

Comments
 (0)