Source code for label_evaluation.iou_scores

# Import third-party libraries
import pandas as pd
import plotly.express as px
import plotly.graph_objs as go
from pathlib import Path
import warnings

# Suppress warnings
warnings.filterwarnings('ignore')

[docs] def calculate_iou(pred_coords: tuple[float, float, float, float], gt_coords: tuple[str, float, float, float, float]) -> float: """ Calculates Intersection over Union (IOU) scores by comparing predicted and ground truth segmentation coordinates. Args: pred_coords (tuple): Coordinates for the predicted bounding box (xmin, ymin, xmax, ymax). gt_coords (tuple): Coordinates for the ground truth bounding box (class, xmin, ymin, xmax, ymax). Returns: float: IOU score. """ try: xmin_pred, ymin_pred, xmax_pred, ymax_pred = pred_coords _, xmin_gt, ymin_gt, xmax_gt, ymax_gt = gt_coords x0_I = max(xmin_pred, xmin_gt) y0_I = max(ymin_pred, ymin_gt) x1_I = min(xmax_pred, xmax_gt) y1_I = min(ymax_pred, ymax_gt) width_I = max(0, x1_I - x0_I) height_I = max(0, y1_I - y0_I) intersection = width_I * height_I width_A, height_A = xmax_pred - xmin_pred, ymax_pred - ymin_pred width_B, height_B = xmax_gt - xmin_gt, ymax_gt - ymin_gt union = (width_A * height_A) + (width_B * height_B) - intersection return intersection / union if union > 0 else 0.0 except Exception as e: print(f"Error calculating IOU: {e}") return 0.0
[docs] def comparison(df_pred_filename: pd.DataFrame, df_gt_filename: pd.DataFrame) -> pd.DataFrame: """ Compare bounding box coordinates and calculate IOU scores. Args: df_pred_filename (pd.DataFrame): DataFrame with predicted labels. df_gt_filename (pd.DataFrame): DataFrame with ground truth labels. Returns: pd.DataFrame: DataFrame with added IOU scores. """ try: max_scores, max_coords = [], {key: [] for key in ['class_gt', 'xmin_gt', 'ymin_gt', 'xmax_gt', 'ymax_gt']} for _, row_pred in df_pred_filename.iterrows(): max_score, best_match = 0, {} pred_coords = (row_pred["xmin_pred"], row_pred["ymin_pred"], row_pred["xmax_pred"], row_pred["ymax_pred"]) for _, row_gt in df_gt_filename.iterrows(): gt_coords = (row_gt["class_gt"], row_gt["xmin_gt"], row_gt["ymin_gt"], row_gt["xmax_gt"], row_gt["ymax_gt"]) iou = calculate_iou(pred_coords, gt_coords) if iou > max_score: max_score, best_match = iou, row_gt max_scores.append(max_score) for key in max_coords: max_coords[key].append(best_match.get(key, None)) df_pred_filename["score"] = max_scores for key, values in max_coords.items(): df_pred_filename[key] = values return df_pred_filename except Exception as e: print(f"Error in comparison: {e}") return pd.DataFrame()
[docs] def concat_frames(df_pred: pd.DataFrame, df_gt: pd.DataFrame) -> pd.DataFrame: """ Concatenate predicted and ground truth datasets with IOU scores. Args: df_pred (pd.DataFrame): DataFrame with predicted bounding boxes. df_gt (pd.DataFrame): DataFrame with ground truth bounding boxes. Returns: pd.DataFrame: Concatenated DataFrame with calculated IOU scores. """ try: df_pred = df_pred.rename(columns={"class": "class_pred", "xmin": "xmin_pred", "ymin": "ymin_pred", "xmax": "xmax_pred", "ymax": "ymax_pred"}) df_gt = df_gt.rename(columns={"class": "class_gt", "xmin": "xmin_gt", "ymin": "ymin_gt", "xmax": "xmax_gt", "ymax": "ymax_gt"}) frames = [comparison(df_pred[df_pred.filename == element], df_gt[df_gt.filename == element]) for element in df_pred.filename.unique()] return pd.concat(frames, ignore_index=True) except Exception as e: print(f"Error concatenating frames: {e}") return pd.DataFrame()
[docs] def box_plot_iou(df_concat: pd.DataFrame, accuracy_txt_path: str = None) -> go.Figure: """ Generate a box plot for IOU scores. Args: df_concat (pd.DataFrame): DataFrame with IOU scores. accuracy_txt_path (str, optional): Path to save accuracy percentages. Returns: go.Figure: Plotly figure object. """ try: fig = px.box( df_concat, y="score", points="all", title="IOU Scores Distribution", labels={"score": "IOU Score"} ) fig.update_layout( width=800, height=600, xaxis=dict(title='Classes', tickfont=dict(size=35)), yaxis=dict(title='IOU Score', tickfont=dict(size=35)), title=dict(text='Label Detection IOU Scores Distribution', font=dict(size=40), x=0.5) ) if accuracy_txt_path: accuracy_percentage = df_concat['score'].mean() * 100 Path(accuracy_txt_path).write_text(f"Overall Accuracy Percentage: {accuracy_percentage:.2f}%\n") return fig except Exception as e: print(f"Error generating box plot: {e}") return go.Figure()