Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
laclouis5 committed Jun 29, 2023
2 parents 1630d18 + a562f54 commit 26ef821
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 32 deletions.
22 changes: 16 additions & 6 deletions src/globox/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ def __init__(
"""
if image_size is not None:
img_w, img_h = image_size
assert img_w > 0 and img_h > 0
assert int(img_w) == img_w and int(img_h) == img_h
assert (
img_w > 0 and img_h > 0
), f"Image size '({img_h}, {img_w})' should be positive."
assert (
int(img_w) == img_w and int(img_h) == img_h
), f"Image size '({img_h}, {img_w})' components should be integers."

self._image_id = image_id
self._image_size = image_size
Expand All @@ -54,8 +58,12 @@ def image_size(self) -> "Optional[tuple[int, int]]":
def image_size(self, image_size: "Optional[tuple[int, int]]"):
if image_size is not None:
img_w, img_h = image_size
assert img_w > 0 and img_h > 0
assert int(img_w) == img_w and int(img_h) == img_h
assert (
img_w > 0 and img_h > 0
), f"Image size '({img_h}, {img_w})' should be positive."
assert (
int(img_w) == img_w and int(img_h) == img_h
), f"Image size '({img_h}, {img_w})' components should be integers."
self._image_size = image_size

@property
Expand Down Expand Up @@ -102,7 +110,9 @@ def from_txt(
path = Path(file_path).expanduser().resolve()

if image_id is None:
assert image_extension.startswith(".")
assert image_extension.startswith(
"."
), f"Image extension '{image_extension}' should start with a dot."
image_id = path.with_suffix(image_extension).name

try:
Expand Down Expand Up @@ -610,7 +620,7 @@ def to_via_json(
) -> dict:
path = Path(image_folder).expanduser().resolve()

assert path.is_dir()
assert path.is_dir(), f"Filepath '{path}' is not a folder or does not exist."

image_id = self.image_id
image_path = path / image_id
Expand Down
24 changes: 16 additions & 8 deletions src/globox/annotationset.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ def from_folder(
) -> "AnnotationSet":
folder = Path(folder).expanduser().resolve()

assert folder.is_dir()
assert (
folder.is_dir()
), f"Filepath '{folder}' is not a folder or does not exist."

files = list(glob(folder, extension, recursive=recursive))
return AnnotationSet.from_iter(parser, files, verbose=verbose)
Expand All @@ -213,8 +215,12 @@ def from_txt(

folder = Path(folder).expanduser().resolve()

assert folder.is_dir()
assert image_extension.startswith(".")
assert (
folder.is_dir()
), f"Filepath '{folder}' is not a folder or does not exist."
assert image_extension.startswith(
"."
), f"Image extension '{image_extension}' should start with a dot."

if relative:
assert image_folder is not None, (
Expand All @@ -224,7 +230,9 @@ def from_txt(

if image_folder is not None:
image_folder = Path(image_folder).expanduser().resolve()
assert image_folder.is_dir()
assert (
image_folder.is_dir()
), f"Filepath '{image_folder}' is not a folder or does not exist."

def _get_annotation(file: Path) -> Annotation:
image_id = file.with_suffix(image_extension).name
Expand Down Expand Up @@ -840,7 +848,7 @@ def save_coco(
if path.suffix == "":
path = path.with_suffix(".json")

assert path.suffix == ".json"
assert path.suffix == ".json", f"Path '{path}' suffix should be '.json'."

content = self.to_coco(
label_to_id=label_to_id,
Expand All @@ -858,7 +866,7 @@ def save_openimage(self, path: PathLike, *, verbose: bool = False):
if path.suffix == "":
path = path.with_suffix(".csv")

assert path.suffix == ".csv"
assert path.suffix == ".csv", f"Path '{path}' suffix should be '.csv'."

fields = (
"ImageID",
Expand Down Expand Up @@ -937,7 +945,7 @@ def save_cvat(self, path: PathLike, *, verbose: bool = False):
if path.suffix == "":
path = path.with_suffix(".xml")

assert path.suffix == ".xml"
assert path.suffix == ".xml", f"Path '{path}' suffix should be '.xml'."

content = self.to_cvat(verbose=verbose)
content = et.tostring(content, encoding="unicode")
Expand Down Expand Up @@ -981,7 +989,7 @@ def save_via_json(
if path.suffix == "":
path = path.with_suffix(".json")

assert path.suffix == ".json"
assert path.suffix == ".json", f"Path '{path}' suffix should be '.json'."

output = self.to_via_json(
image_folder=image_folder,
Expand Down
2 changes: 1 addition & 1 deletion src/globox/boundingbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ def to_cvat(self) -> et.Element:
def to_via_json(
self, *, label_key: str = "label_id", confidence_key: str = "confidence"
) -> dict:
assert label_key != confidence_key
assert label_key != confidence_key, f"Label key '{label_key}' and confidence key '{confidence_key}' should be different."

shape_attributes = {
"name": "rect",
Expand Down
4 changes: 3 additions & 1 deletion src/globox/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,9 @@ def evaluate(
def main():
args = parse_args()

assert args.threads is None or args.threads > 0
assert (
args.threads is None or args.threads > 0
), f"The number of threads '{args.threads}' should either be None or be greater than 0."

mode = args.mode
if mode == "convert":
Expand Down
6 changes: 1 addition & 5 deletions src/globox/errors.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
from pathlib import Path


class BaseException(Exception):
pass


class UnknownImageFormat(BaseException):
class UnknownImageFormat(Exception):
pass


Expand Down
38 changes: 28 additions & 10 deletions src/globox/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ def __init__(
self._npos = npos
self._cache: dict[str, Any] = {}

assert self._npos >= 0
assert len(self._tps) == len(self._scores)
assert self._npos >= 0, f"'npos' ({npos}) should be greater than or equal to 0."
assert len(self._tps) == len(
self._scores
), f"The number of 'tps' ({len(self._tps)}) should be equal to the number of 'scores' ({len(self._scores)})."

def __iadd__(self, other: "PartialEvaluationItem") -> "PartialEvaluationItem":
self._tps += other._tps
Expand Down Expand Up @@ -442,7 +444,9 @@ def evaluate_annotation(
size_range: "tuple[float, float]",
labels: Optional[Iterable[str]] = None,
) -> PartialEvaluation:
assert prediction.image_id == ground_truth.image_id
assert (
prediction.image_id == ground_truth.image_id
), f"The prediction image id '{prediction.image_id}' should be the same as the ground truth image id '{ground_truth.image_id}'."

preds = grouping(prediction.boxes, lambda box: box.label)
refs = grouping(ground_truth.boxes, lambda box: box.label)
Expand All @@ -468,10 +472,18 @@ def evaluate_boxes(
max_detections: int,
size_range: "tuple[float, float]",
) -> PartialEvaluationItem:
assert all(p.is_detection for p in predictions)
assert all(g.is_ground_truth for g in ground_truths)
assert all_equal(p.label for p in predictions)
assert all_equal(g.label for g in ground_truths)
assert all(
p.is_detection for p in predictions
), f"Prediction annotations should not contain ground truth annotations."
assert all(
g.is_ground_truth for g in ground_truths
), f"Ground truth annotations should not contain prediction annotations."
assert all_equal(
p.label for p in predictions
), f"The prediction boxes should have the same label."
assert all_equal(
g.label for g in ground_truths
), f"The ground truth boxes should have the same label."

cls._assert_params(iou_threshold, max_detections, size_range)

Expand Down Expand Up @@ -523,11 +535,17 @@ def evaluate_boxes(
def _assert_params(
iou_threshold: float, max_detections: int, size_range: "tuple[float, float]"
):
assert 0.0 <= iou_threshold <= 1.0
assert max_detections >= 0
assert (
0.0 <= iou_threshold <= 1.0
), f"the IoU threshold ({iou_threshold}) should be between 0 and 1."
assert (
max_detections >= 0
), f"The maximum number of detections ({max_detections}) should be positive."

low, high = size_range
assert low >= 0.0 and high >= low
assert (
low >= 0.0 and high >= low
), f"The size range '({low}, {high})' should be positive and non-empty, i.e. 0 < size_range[0] <= size_range[1]."

def clear_cache(self):
self._cached_evaluate.cache_clear()
Expand Down
2 changes: 1 addition & 1 deletion src/globox/file_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def glob(

assert all(
e.startswith(".") for e in extensions
), "Parameter `extension` should start with a dot."
), f"Parameter `extensions' ({extensions}) should all start with a dot."

path = Path(folder).expanduser().resolve()

Expand Down

0 comments on commit 26ef821

Please sign in to comment.