santit96's picture
Create the streamlit app that classifies the trash in an image into classes
fa84113
""" COCO dataset parser
Copyright 2020 Ross Wightman
"""
import numpy as np
from pycocotools.coco import COCO
from .parser import Parser
from .parser_config import CocoParserCfg
class CocoParser(Parser):
def __init__(self, cfg: CocoParserCfg):
super().__init__(
bbox_yxyx=cfg.bbox_yxyx,
has_labels=cfg.has_labels,
include_masks=cfg.include_masks,
include_bboxes_ignore=cfg.include_bboxes_ignore,
ignore_empty_gt=cfg.has_labels and cfg.ignore_empty_gt,
min_img_size=cfg.min_img_size
)
self.cat_ids_as_labels = True # this is the default for original TF EfficientDet models
self.coco = None
self._load_annotations(cfg.ann_filename)
def get_ann_info(self, idx):
img_id = self.img_ids[idx]
return self._parse_img_ann(img_id)
def _load_annotations(self, ann_file):
assert self.coco is None
self.coco = COCO(ann_file)
self.cat_ids = self.coco.getCatIds()
self.cat_names = [c['name'] for c in self.coco.loadCats(ids=self.cat_ids)]
if not self.cat_ids_as_labels:
self.cat_id_to_label = {cat_id: i + self.label_offset for i, cat_id in enumerate(self.cat_ids)}
img_ids_with_ann = set(_['image_id'] for _ in self.coco.anns.values())
for img_id in sorted(self.coco.imgs.keys()):
info = self.coco.loadImgs([img_id])[0]
if (min(info['width'], info['height']) < self.min_img_size or
(self.ignore_empty_gt and img_id not in img_ids_with_ann)):
self.img_ids_invalid.append(img_id)
continue
self.img_ids.append(img_id)
self.img_infos.append(info)
def _parse_img_ann(self, img_id):
ann_ids = self.coco.getAnnIds(imgIds=[img_id])
ann_info = self.coco.loadAnns(ann_ids)
bboxes = []
bboxes_ignore = []
cls = []
for i, ann in enumerate(ann_info):
if ann.get('ignore', False):
continue
x1, y1, w, h = ann['bbox']
if self.include_masks and ann['area'] <= 0:
continue
if w < 1 or h < 1:
continue
if self.yxyx:
bbox = [y1, x1, y1 + h, x1 + w]
else:
bbox = [x1, y1, x1 + w, y1 + h]
if ann.get('iscrowd', False):
if self.include_bboxes_ignore:
bboxes_ignore.append(bbox)
else:
bboxes.append(bbox)
cls.append(self.cat_id_to_label[ann['category_id']] if self.cat_id_to_label else ann['category_id'])
if bboxes:
bboxes = np.array(bboxes, ndmin=2, dtype=np.float32)
cls = np.array(cls, dtype=np.int64)
else:
bboxes = np.zeros((0, 4), dtype=np.float32)
cls = np.array([], dtype=np.int64)
if self.include_bboxes_ignore:
if bboxes_ignore:
bboxes_ignore = np.array(bboxes_ignore, ndmin=2, dtype=np.float32)
else:
bboxes_ignore = np.zeros((0, 4), dtype=np.float32)
ann = dict(bbox=bboxes, cls=cls)
if self.include_bboxes_ignore:
ann['bbox_ignore'] = bboxes_ignore
return ann