from collections import defaultdict
import numpy as np
from .error import Error, BestGTMatch
class ClassError(Error):
description = "Error caused when a prediction would have been marked positive " \
+ "if it had the correct class."
short_name = "Cls"
def __init__(self, pred:dict, gt:dict, ex):
self.pred = pred
self.gt = gt
self.match = BestGTMatch(pred, gt) if not self.gt['used'] else None
def fix(self):
if self.match is None:
return None
return self.gt['class'], self.match.fix()
class BoxError(Error):
description = "Error caused when a prediction would have been marked positive if it was localized better."
short_name = "Loc"
def __init__(self, pred:dict, gt:dict, ex):
self.pred = pred
self.gt = gt
self.match = BestGTMatch(pred, gt) if not self.gt['used'] else None
def fix(self):
if self.match is None:
return None
return self.pred['class'], self.match.fix()
class DuplicateError(Error):
description = "Error caused when a prediction would have been marked positive " \
+ "if the GT wasn't already in use by another detection."
short_name = "Dupe"
def __init__(self, pred:dict, suppressor: dict):
self.pred = pred
self.suppressor = suppressor
def fix(self):
return None
class BackgroundError(Error):
description = "Error caused when this detection should have been classified as background (IoU < 0.1)."
short_name = "Bkg"
def __init__(self, pred:dict):
self.pred = pred
def fix(self):
return None
class OtherError(Error):
description = "This detection didn't fall into any of the other error categories."
short_name = "Both"
def __init__(self, pred:dict):
self.pred = pred
def fix(self):
return None
class MissedError(Error):
description = "Represents GT missed by the model. Doesn't include GT corrected elsewhere in the model."
short_name = "Miss"
def __init__(self, gt:dict):
self.gt = gt
def fix(self):
return self.gt['class'], -1
class FalsePositiveError:
description = "Represents the potential AP gained by having perfect precision" \
+ " (e.g., by scoring all false positives as conf=0) without affecting recall."
short_name = "FalsePos"
@staticmethod
def fix(score:float, correct:bool, info:dict) -> tuple:
if correct:
return 1, True, info
else:
return 0, False, info
class FalseNegativeError:
description = "Represents the potentially AP gained by having perfect recall" \
+ " without affecting precision."
short_name = "FalseNeg"