Skip to content

Commit 8e8c19e

Browse files
author
Matt Sokoloff
committed
docstrings
1 parent 233a109 commit 8e8c19e

File tree

4 files changed

+55
-20
lines changed

4 files changed

+55
-20
lines changed

examples/integrations/detectron2/coco_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def partition_coco(coco_instance_data, coco_panoptic_data = None, splits = None)
4747
return partitions
4848

4949

50-
def visualize_coco_examples(coco_examples, metadata_catalog, scale = 1.0, max_images = 5, resize_dims = (512,768)):
50+
def visualize_coco_examples(coco_examples, metadata_catalog, scale = 1.0, max_images = 5, resize_dims = (768, 512)):
5151
images = []
5252
for idx, example in enumerate(coco_examples):
5353
if idx > max_images:

labelbox/data/serialization/coco/converter.py

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# Mapping can be used to select classes as instsance or segmentation
2-
# By default polygon will be instance and segmentation will be semantic
3-
4-
# Will use subclasses too..
5-
# checklist and radio will be turned into underscore delimitated names
61
from typing import Dict, Any
72
import os
83

@@ -14,27 +9,37 @@
149
def create_path_if_not_exists(path: str):
1510
if not os.path.exists(path):
1611
os.makedirs(path)
12+
elif os.path.listdir(path):
13+
raise ValueError(f"Directory `{path}`` must be empty.")
1714

1815

1916
def validate_path(path, name):
2017
if not os.path.exists(path):
21-
raise ValueError(f"{name} {path} must exist")
18+
raise ValueError(f"{name} `{path}` must exist")
2219

2320

2421
class COCOConverter:
2522
"""
26-
Note that this class is only compatible with image data.. it will ignore other data types.
27-
# TODO: Filter out video annotations..
28-
23+
Class for convertering between coco and labelbox formats
24+
Note that this class is only compatible with image data.
2925
30-
# Note that these functions are not compatible with subclasses currently.
31-
# If you have subclasses you will have to manually flatten them before using the converter.
26+
Subclasses are currently ignored.
27+
To use subclasses, manually flatten them before using the converter.
3228
"""
3329

3430
def serialize_instances(labels: LabelCollection,
3531
image_root: str) -> Dict[str, Any]:
3632
"""
37-
Compatible with masks, polygons, and masks. Will turn masks into individual instances
33+
Convert a Labelbox LabelCollection into an mscoco dataset.
34+
This function will only convert masks, polygons, and rectangles.
35+
Masks will be converted into individual instances.
36+
Use deserialize_panoptic to prevent masks from being split apart.
37+
38+
Args:
39+
labels: A collection of labels to convert
40+
image_root: Where to save images to
41+
Returns:
42+
A dictionary containing labels in the coco object format.
3843
"""
3944
create_path_if_not_exists(image_root)
4045
return CocoInstanceDataset.from_common(labels=labels,
@@ -43,8 +48,19 @@ def serialize_instances(labels: LabelCollection,
4348
def serialize_panoptic(labels: LabelCollection, image_root: str,
4449
mask_root: str, all_stuff: bool = False) -> Dict[str, Any]:
4550
"""
46-
All stuff turns every class into segmentation classes
51+
Convert a Labelbox LabelCollection into an mscoco dataset.
52+
This function will only convert masks, polygons, and rectangles.
53+
Masks will be converted into individual instances.
54+
Use deserialize_panoptic to prevent masks from being split apart.
4755
56+
Args:
57+
labels: A collection of labels to convert
58+
image_root: Where to save images to
59+
mask_root: Where to save segmentation masks to
60+
all_stuff: If rectangle or polygon annotations are encountered, they will be treated as instances.
61+
To convert them to stuff class set `all_stuff=True`.
62+
Returns:
63+
A dictionary containing labels in the coco panoptic format.
4864
"""
4965
create_path_if_not_exists(image_root)
5066
create_path_if_not_exists(mask_root)
@@ -55,6 +71,16 @@ def serialize_panoptic(labels: LabelCollection, image_root: str,
5571
@classmethod
5672
def deserialize_panoptic(cls, json_data: Dict[str, Any], image_root: str,
5773
mask_root: str) -> LabelGenerator:
74+
"""
75+
Convert coco panoptic data into the labelbox format (as a LabelGenerator).
76+
77+
Args:
78+
json_data: panoptic data as a dict
79+
image_root: Path to local images that are referenced by the panoptic json
80+
mask_root: Path to local segmentation masks that are referenced by the panoptic json
81+
Returns:
82+
LabelGenerator
83+
"""
5884
validate_path(image_root, 'image_root')
5985
validate_path(mask_root, 'mask_root')
6086
objs = CocoPanopticDataset(**json_data)
@@ -64,6 +90,15 @@ def deserialize_panoptic(cls, json_data: Dict[str, Any], image_root: str,
6490
@classmethod
6591
def deserialize_instances(cls, json_data: Dict[str, Any],
6692
image_root: str) -> LabelGenerator:
93+
"""
94+
Convert coco object data into the labelbox format (as a LabelGenerator).
95+
96+
Args:
97+
json_data: coco object data as a dict
98+
image_root: Path to local images that are referenced by the coco object json
99+
Returns:
100+
LabelGenerator
101+
"""
67102
validate_path(image_root, 'image_root')
68103
objs = CocoInstanceDataset(**json_data)
69104
gen = objs.to_common(image_root)

labelbox/data/serialization/coco/instance_dataset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ def segmentations_to_common(class_annotations, class_name):
8282
return annotations
8383

8484

85-
def process_label(label: Label, idx, image_root):
86-
annot_idx = idx * 10000
85+
def process_label(label: Label, idx, image_root, max_annotations_per_image = 10000):
86+
annot_idx = idx * max_annotations_per_image
8787
image_id = get_image_id(label, idx)
8888
image = get_image(label, image_root, image_id)
8989
coco_annotations = []

labelbox/data/serialization/coco/panoptic_dataset.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def vector_to_coco_segment_info(canvas: np.ndarray,
3030
return SegmentInfo(id=annotation_idx,
3131
category_id=category_id,
3232
area=shapely.area,
33-
bbox=[xmin, ymin, xmax - xmin, ymax - ymin])
33+
bbox=[xmin, ymin, xmax - xmin, ymax - ymin]), canvas
3434

3535

3636
def mask_to_coco_segment_info(canvas: np.ndarray, annotation, annotation_idx: int, category_id):
@@ -69,13 +69,13 @@ def process_label(label: Label, idx: Union[int, str], image_root, mask_root, all
6969
is_thing[annotation.name] = 0
7070

7171
elif isinstance(annotation.value, (Polygon, Rectangle)):
72-
segments.append(
73-
vector_to_coco_segment_info(
72+
segment, canvas = vector_to_coco_segment_info(
7473
canvas,
7574
annotation,
7675
annotation_idx=(class_idx if all_stuff else annotation_idx) + 1,
7776
image=image,
78-
category_id=categories[annotation.name]))
77+
category_id=categories[annotation.name])
78+
segments.append(segment)
7979
is_thing[annotation.name] = 1 - int(all_stuff)
8080

8181
mask_file = image.file_name.replace('.jpg', '.png')

0 commit comments

Comments
 (0)