|
6 | 6 | "coco_api_from_records",
|
7 | 7 | "coco_api_from_preds",
|
8 | 8 | "create_coco_eval",
|
9 |
| - "export_batch_inferences_as_coco_annotations", |
10 | 9 | ]
|
11 | 10 |
|
12 | 11 | from icevision.imports import *
|
13 | 12 | from icevision.utils import *
|
14 | 13 | from icevision.core import *
|
15 | 14 | from pycocotools.coco import COCO
|
16 | 15 | from pycocotools.cocoeval import COCOeval
|
17 |
| -import json |
18 |
| -import numpy as np |
19 |
| -import PIL |
20 |
| - |
21 |
| - |
22 |
| -class NpEncoder(json.JSONEncoder): |
23 |
| - """ |
24 |
| - Smooths out datatype conversions for IceVision preds to JSON export |
25 |
| - """ |
26 |
| - |
27 |
| - def default(self, obj): |
28 |
| - if isinstance(obj, np.integer): |
29 |
| - return int(obj) |
30 |
| - if isinstance(obj, np.floating): |
31 |
| - return float(obj) |
32 |
| - if isinstance(obj, np.ndarray): |
33 |
| - return obj.tolist() |
34 |
| - return json.JSONEncoder.default(self, obj) |
35 |
| - |
36 |
| - |
37 |
| -def export_batch_inferences_as_coco_annotations( |
38 |
| - preds, |
39 |
| - img_files, |
40 |
| - transforms, |
41 |
| - class_map, |
42 |
| - output_filepath="inference_results_as_coco_annotations.json", |
43 |
| - info=None, |
44 |
| - licenses=None, |
45 |
| -): |
46 |
| - """ |
47 |
| - For converting object detection predictions to COCO annotation format. |
48 |
| - Useful for e.g. leveraging partly-trained models to help annotate |
49 |
| - unlabeled data and make round trips back into annotation programs. |
50 |
| -
|
51 |
| - Parameters |
52 |
| - ---------- |
53 |
| - preds : List[Prediction] |
54 |
| - The result of predict_from_dl() |
55 |
| - img_files : fastcore.foundation.L (i.e. 'Paths') |
56 |
| - References to the original image filepaths in array-like form. |
57 |
| - transforms : Albumentations Adapter |
58 |
| - Transforms that were applied to the original images (to be reversed) |
59 |
| - class_map : icevision.core.class_map.ClassMap |
60 |
| - The map of classes your model is familiar with |
61 |
| - output_filepath : str, optional |
62 |
| - The filepath (including filename) where you want the json results |
63 |
| - to be serialized, by default |
64 |
| - "new_pseudo_labels_for_further_training.json" |
65 |
| - info: dict, optional |
66 |
| - Option to manually create the info dict containing annotation metadata |
67 |
| - including year, version, description, contributor, url, and date created |
68 |
| - For example: |
69 |
| - "info": { |
70 |
| - "year": "2022", |
71 |
| - "version": "1", |
72 |
| - "description": "Exported from IceVision", |
73 |
| - "contributor": "Awesome contributor", |
74 |
| - "url": "https://lazyannotator.fun", |
75 |
| - "date_created": "2022-08-05T20:13:09+00:00" |
76 |
| - } |
77 |
| - licenses: List[dict], optional |
78 |
| - Option to manually create the license metadata for the annotations, e.g. |
79 |
| - licenses = [ |
80 |
| - { |
81 |
| - "name": "Creative Commons Attribution 4.0", |
82 |
| - "id": 0, |
83 |
| - "url": "https://creativecommons.org/licenses/by/4.0/legalcode", |
84 |
| - } |
85 |
| - ] |
86 |
| -
|
87 |
| - Returns |
88 |
| - ------- |
89 |
| - None |
90 |
| - This just spits out a serialized .json file and returns nothing. |
91 |
| - """ |
92 |
| - object_category_list = [ |
93 |
| - {"id": v, "name": k, "supercategory": ""} |
94 |
| - for k, v in class_map._class2id.items() |
95 |
| - ] |
96 |
| - |
97 |
| - if info is None: |
98 |
| - # Then automatically generate COCO annotation metadata: |
99 |
| - info = { |
100 |
| - "contributor": "", |
101 |
| - "date_created": "", |
102 |
| - "description": "", |
103 |
| - "url": "", |
104 |
| - "version": "", |
105 |
| - "year": "", |
106 |
| - } |
107 |
| - |
108 |
| - if licenses is None: |
109 |
| - licenses = [ |
110 |
| - { |
111 |
| - "name": "", |
112 |
| - "id": 0, |
113 |
| - "url": "", |
114 |
| - } |
115 |
| - ] |
116 |
| - |
117 |
| - addl_info = { |
118 |
| - "licenses": licenses, |
119 |
| - "info": info, |
120 |
| - "categories": object_category_list, |
121 |
| - } |
122 |
| - |
123 |
| - # Each entry needs a filepath |
124 |
| - [pred.add_component(FilepathRecordComponent()) for pred in preds] |
125 |
| - [preds[_].set_filepath(img_files[_]) for _ in range(len(preds))] |
126 |
| - |
127 |
| - # process_bbox_predictions happens inplace, thus no new variable |
128 |
| - for p in preds: |
129 |
| - process_bbox_predictions( |
130 |
| - p, PIL.Image.open(Path(p.pred.filepath)), transforms.tfms_list |
131 |
| - ) |
132 |
| - |
133 |
| - coco_style_preds = convert_preds_to_coco_style(preds) |
134 |
| - imgs_array = [PIL.Image.open(Path(fname)) for fname in img_files] |
135 |
| - |
136 |
| - sizes = [{"x": img._size[0], "y": img._size[1]} for img in imgs_array] |
137 |
| - |
138 |
| - for idx, image in enumerate(coco_style_preds["images"]): |
139 |
| - coco_style_preds["images"][idx]["width"] = sizes[idx]["x"] |
140 |
| - coco_style_preds["images"][idx]["height"] = sizes[idx]["y"] |
141 |
| - |
142 |
| - finalized_pseudo_labels = {**addl_info, **coco_style_preds} |
143 |
| - |
144 |
| - # Serialize |
145 |
| - with open(output_filepath, "w") as jfile: |
146 |
| - json.dump(finalized_pseudo_labels, jfile, cls=NpEncoder) |
147 |
| - |
148 |
| - # Print confirmation message |
149 |
| - print(f"New COCO annotation file saved to {output_filepath}") |
150 | 16 |
|
151 | 17 |
|
152 | 18 | def create_coco_api(coco_records) -> COCO:
|
|
0 commit comments