CoolFace
Apppublic

karolmajek/Axial-DeepLab-SWideRNet

sourceHugging Faceupdated 5y agoView on Hugging Face
0likes
coco_tools.py202 linesDownload Raw Back to utils
1# coding=utf-82# Copyright 2021 The Deeplab2 Authors.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8#     http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15 16"""Wrappers and conversions for third party pycocotools.17 18This is derived from code in the Tensorflow Object Detection API:19https://github.com/tensorflow/models/tree/master/research/object_detection20 21Huang et. al. "Speed/accuracy trade-offs for modern convolutional object22detectors" CVPR 2017.23"""24 25from typing import Any, Collection, Dict, List, Optional, Union26 27import numpy as np28from pycocotools import mask29 30 31COCO_METRIC_NAMES_AND_INDEX = (32    ('Precision/mAP', 0),33    ('Precision/mAP@.50IOU', 1),34    ('Precision/mAP@.75IOU', 2),35    ('Precision/mAP (small)', 3),36    ('Precision/mAP (medium)', 4),37    ('Precision/mAP (large)', 5),38    ('Recall/AR@1', 6),39    ('Recall/AR@10', 7),40    ('Recall/AR@100', 8),41    ('Recall/AR@100 (small)', 9),42    ('Recall/AR@100 (medium)', 10),43    ('Recall/AR@100 (large)', 11)44)45 46 47def _ConvertBoxToCOCOFormat(box: np.ndarray) -> List[float]:48  """Converts a box in [ymin, xmin, ymax, xmax] format to COCO format.49 50  This is a utility function for converting from our internal51  [ymin, xmin, ymax, xmax] convention to the convention used by the COCO API52  i.e., [xmin, ymin, width, height].53 54  Args:55    box: a [ymin, xmin, ymax, xmax] numpy array56 57  Returns:58    a list of floats representing [xmin, ymin, width, height]59  """60  return [float(box[1]), float(box[0]), float(box[3] - box[1]),61          float(box[2] - box[0])]62 63 64def ExportSingleImageGroundtruthToCoco(65    image_id: Union[int, str],66    next_annotation_id: int,67    category_id_set: Collection[int],68    groundtruth_boxes: np.ndarray,69    groundtruth_classes: np.ndarray,70    groundtruth_masks: np.ndarray,71    groundtruth_is_crowd: Optional[np.ndarray] = None) -> List[Dict[str, Any]]:72  """Exports groundtruth of a single image to COCO format.73 74  This function converts groundtruth detection annotations represented as numpy75  arrays to dictionaries that can be ingested by the COCO evaluation API. Note76  that the image_ids provided here must match the ones given to77  ExportSingleImageDetectionsToCoco. We assume that boxes and classes are in78  correspondence - that is: groundtruth_boxes[i, :], and79  groundtruth_classes[i] are associated with the same groundtruth annotation.80 81  In the exported result, "area" fields are always set to the foregorund area of82  the mask.83 84  Args:85    image_id: a unique image identifier either of type integer or string.86    next_annotation_id: integer specifying the first id to use for the87      groundtruth annotations. All annotations are assigned a continuous integer88      id starting from this value.89    category_id_set: A set of valid class ids. Groundtruth with classes not in90      category_id_set are dropped.91    groundtruth_boxes: numpy array (float32) with shape [num_gt_boxes, 4]92    groundtruth_classes: numpy array (int) with shape [num_gt_boxes]93    groundtruth_masks: uint8 numpy array of shape [num_detections, image_height,94      image_width] containing detection_masks.95    groundtruth_is_crowd: optional numpy array (int) with shape [num_gt_boxes]96      indicating whether groundtruth boxes are crowd.97 98  Returns:99    a list of groundtruth annotations for a single image in the COCO format.100 101  Raises:102    ValueError: if (1) groundtruth_boxes and groundtruth_classes do not have the103      right lengths or (2) if each of the elements inside these lists do not104      have the correct shapes or (3) if image_ids are not integers105  """106 107  if len(groundtruth_classes.shape) != 1:108    raise ValueError('groundtruth_classes is '109                     'expected to be of rank 1.')110  if len(groundtruth_boxes.shape) != 2:111    raise ValueError('groundtruth_boxes is expected to be of '112                     'rank 2.')113  if groundtruth_boxes.shape[1] != 4:114    raise ValueError('groundtruth_boxes should have '115                     'shape[1] == 4.')116  num_boxes = groundtruth_classes.shape[0]117  if num_boxes != groundtruth_boxes.shape[0]:118    raise ValueError('Corresponding entries in groundtruth_classes, '119                     'and groundtruth_boxes should have '120                     'compatible shapes (i.e., agree on the 0th dimension).'121                     'Classes shape: %d. Boxes shape: %d. Image ID: %s' % (122                         groundtruth_classes.shape[0],123                         groundtruth_boxes.shape[0], image_id))124  has_is_crowd = groundtruth_is_crowd is not None125  if has_is_crowd and len(groundtruth_is_crowd.shape) != 1:126    raise ValueError('groundtruth_is_crowd is expected to be of rank 1.')127  groundtruth_list = []128  for i in range(num_boxes):129    if groundtruth_classes[i] in category_id_set:130      iscrowd = groundtruth_is_crowd[i] if has_is_crowd else 0131      segment = mask.encode(np.asfortranarray(groundtruth_masks[i]))132      area = mask.area(segment)133      export_dict = {134          'id': next_annotation_id + i,135          'image_id': image_id,136          'category_id': int(groundtruth_classes[i]),137          'bbox': list(_ConvertBoxToCOCOFormat(groundtruth_boxes[i, :])),138          'segmentation': segment,139          'area': area,140          'iscrowd': iscrowd141      }142 143      groundtruth_list.append(export_dict)144  return groundtruth_list145 146 147def ExportSingleImageDetectionMasksToCoco(148    image_id: Union[int, str], category_id_set: Collection[int],149    detection_masks: np.ndarray, detection_scores: np.ndarray,150    detection_classes: np.ndarray) -> List[Dict[str, Any]]:151  """Exports detection masks of a single image to COCO format.152 153  This function converts detections represented as numpy arrays to dictionaries154  that can be ingested by the COCO evaluation API. We assume that155  detection_masks, detection_scores, and detection_classes are in correspondence156  - that is: detection_masks[i, :], detection_classes[i] and detection_scores[i]157    are associated with the same annotation.158 159  Args:160    image_id: unique image identifier either of type integer or string.161    category_id_set: A set of valid class ids. Detections with classes not in162      category_id_set are dropped.163    detection_masks: uint8 numpy array of shape [num_detections, image_height,164      image_width] containing detection_masks.165    detection_scores: float numpy array of shape [num_detections] containing166      scores for detection masks.167    detection_classes: integer numpy array of shape [num_detections] containing168      the classes for detection masks.169 170  Returns:171    a list of detection mask annotations for a single image in the COCO format.172 173  Raises:174    ValueError: if (1) detection_masks, detection_scores and detection_classes175      do not have the right lengths or (2) if each of the elements inside these176      lists do not have the correct shapes or (3) if image_ids are not integers.177  """178 179  if len(detection_classes.shape) != 1 or len(detection_scores.shape) != 1:180    raise ValueError('All entries in detection_classes and detection_scores'181                     'expected to be of rank 1.')182  num_boxes = detection_classes.shape[0]183  if not num_boxes == len(detection_masks) == detection_scores.shape[0]:184    raise ValueError('Corresponding entries in detection_classes, '185                     'detection_scores and detection_masks should have '186                     'compatible lengths and shapes '187                     'Classes length: %d.  Masks length: %d. '188                     'Scores length: %d' % (189                         detection_classes.shape[0], len(detection_masks),190                         detection_scores.shape[0]191                     ))192  detections_list = []193  for i in range(num_boxes):194    if detection_classes[i] in category_id_set:195      detections_list.append({196          'image_id': image_id,197          'category_id': int(detection_classes[i]),198          'segmentation': mask.encode(np.asfortranarray(detection_masks[i])),199          'score': float(detection_scores[i])200      })201  return detections_list202