sidescanpy.export.ml.coco#
COCO-format export for sonar targets.
Scoped to JSF for now: one canonical crop image + one bounding-box
annotation per target, single category (no real class labels are assumed — Description/Tag are
commonly empty), defaulting to min_confidence="verified" so a dataset export
can’t silently ship unlocalized or low-confidence boxes.
The bbox itself is a fixed placeholder size (box_size), not a
measured target dimension — no source catalog seen so far has real
LengthMeters/WidthMeters data. This is recorded in the written
JSON’s own info.description so the caveat travels with the file, not
just with whatever presentation wraps it.
2026 rshomberg@uri.edu
Contents
One target's canonical crop, ready to become a COCO image+annotation. |
|
Ordered class names for |
|
Write |
- class sidescanpy.export.ml.coco.CocoImageEntry(target, file_name, width, height, bbox_size=None)#
Bases:
objectOne target’s canonical crop, ready to become a COCO image+annotation.
Multiple entries may share the same
file_name— e.g. every cataloged target that falls within one exported window (seesidescanpy.export.windows.targets_within_window). They become one shared COCO image record with one annotation per entry, rather than one image per target. Every entry sharing afile_namemust agree onwidth/height(the same physical image).bbox_size, if given, overrideswrite_coco/write_yolo’s globalbox_sizefor this entry only — for a real, measured target extent instead of the shared placeholder.target=Nonerecords an image with no annotations (a background image): COCO gets the image record alone, YOLO an empty label file. Such entries bypass the confidence filter.
- sidescanpy.export.ml.coco.resolve_categories(entries, category_name='target', categories=None)#
Ordered class names for
entries(index + 1 is the COCO id, index is the YOLO class).Uncategorized targets (
Target.category is None) belong tocategory_name. With no explicitcategories: the sorted set of names present (just[category_name]when nothing is categorized). With an explicit orderedcategorieslist, that list is returned as-is so ids stay stable across separately-exported datasets.- Raises:
- ValueError
If
categorieshas duplicates, or a target’s category is not in it.
- sidescanpy.export.ml.coco.write_coco(entries, output_path, *, category_name='target', box_size=(40.0, 40.0), min_confidence='verified', categories=None)#
Write
entriestooutput_pathas a COCO-format JSON dataset.Per-annotation class comes from
Target.category(None->category_name). Thecategorieslist is the sorted set of names present with ids 1..N, or, ifcategoriesis given, that explicit ordered list (seeresolve_categories()). With no categorized targets the output is the singlecategory_namecategory, id 1.Only targets with
position_confidenceat or abovemin_confidence(orderedunknown < approximate < verified) are included — passmin_confidence="approximate"or"unknown"explicitly to include lower-confidence targets; this must be an opt-in, not the default, per the design doc’s own rationale (a prior export in a sibling project shipped an unverified/wrong bounding-box hypothesis by not gating on this).Entries sharing a
file_namebecome one image with multiple annotations (seeCocoImageEntry’s own docstring) — each entry’s ownbbox_size(if set) is used for its box, else the sharedbox_size. An entry withtarget=Noneadds its image with no annotation.Returns the dict that was written, for inline inspection/testing.
- Raises:
- ValueError
If two entries share a
file_namebut disagree onwidth/height.