-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcoco_test_dev_json.py
More file actions
175 lines (130 loc) · 5.73 KB
/
Copy pathcoco_test_dev_json.py
File metadata and controls
175 lines (130 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
"""
ContourFormer:Real-Time Contour-Based End-to-End Instance Segmentation Transformer
Copyright (c) 2025 The ContourFormer Authors. All Rights Reserved.
---------------------------------------------------------------------------------
Modified from D-FINE (https://github.com/Peterande/D-FINE)
Copyright (c) 2024 Peterande. All Rights Reserved.
"""
import torch
from PIL import ImageFile
from PIL import Image
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = 2800000000
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
import json
import argparse
import numpy as np
import pycocotools.mask as mask_util
from src.misc import dist_utils,MetricLogger, SmoothedValue
from src.core import YAMLConfig, yaml_utils
from src.solver import TASKS
debug=False
if debug:
import torch
def custom_repr(self):
return f'{{Tensor:{tuple(self.shape)}}} {original_repr(self)}'
original_repr = torch.Tensor.__repr__
torch.Tensor.__repr__ = custom_repr
def prepare_for_coco_segmentation(predictions):
coco_results = []
for original_id, prediction in predictions.items():
if len(prediction) == 0:
continue
keep = prediction["scores"]>0.1
scores = prediction["scores"][keep]
labels = prediction["labels"][keep]
masks = prediction["masks"][keep.cpu().numpy()]
masks = masks > 0.5
scores = prediction["scores"].tolist()
labels = prediction["labels"].tolist()
rles = [
mask_util.encode(np.array(mask[0, :, :, np.newaxis], dtype=np.uint8, order="F"))[0]
for mask in masks
]
for rle in rles:
rle["counts"] = rle["counts"].decode("utf-8")
coco_results.extend(
[
{
"image_id": original_id,
"category_id": labels[k],
"segmentation": rle,
"score": round(scores[k], 4),
}
for k, rle in enumerate(rles)
]
)
return coco_results
@torch.no_grad()
def evaluate(model: torch.nn.Module, postprocessor, data_loader, device,output_name):
model.eval()
coco_results = []
metric_logger = MetricLogger(delimiter=" ")
# metric_logger.add_meter('class_error', SmoothedValue(window_size=1, fmt='{value:.2f}'))
header = 'Test:'
for samples, targets in metric_logger.log_every(data_loader, 10, header):
samples = samples.to(device)
targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
outputs = model(samples)
# with torch.autocast(device_type=str(device)):
# outputs = model(samples)
# TODO (lyuwenyu), fix dataset converted using `convert_to_coco_api`?
orig_target_sizes = torch.stack([t["orig_size"] for t in targets], dim=0)
input_sizes = torch.tensor([[samples.shape[-1], samples.shape[-2]]], device=samples.device)
# orig_target_sizes = torch.tensor([[samples.shape[-1], samples.shape[-2]]], device=samples.device)
results = postprocessor(outputs, orig_target_sizes, input_sizes)
# if 'segm' in postprocessor.keys():
# target_sizes = torch.stack([t["size"] for t in targets], dim=0)
# results = postprocessor['segm'](results, outputs, orig_target_sizes, target_sizes)
res = {target['image_id'].item(): output for target, output in zip(targets, results)}
results = prepare_for_coco_segmentation(res)
coco_results.extend(results)
# gather the stats from all processes
metric_logger.synchronize_between_processes()
all_coco_results = dist_utils.all_gather(coco_results)
if dist_utils.is_main_process():
merge_coco_results = []
for p in all_coco_results:
merge_coco_results.extend(p)
json.dump(merge_coco_results,open(output_name,"w"))
return
def main(args, ) -> None:
"""main
"""
dist_utils.setup_distributed(args.print_rank, args.print_method, seed=args.seed)
assert not all([args.tuning, args.resume]), \
'Only support from_scrach or resume or tuning at one time'
update_dict = yaml_utils.parse_cli(args.update)
update_dict.update({k: v for k, v in args.__dict__.items() \
if k not in ['update', ] and v is not None})
cfg = YAMLConfig(args.config, **update_dict)
if args.resume or args.tuning:
if 'HGNetv2' in cfg.yaml_cfg:
cfg.yaml_cfg['HGNetv2']['pretrained'] = False
print('cfg: ', cfg.__dict__)
solver = TASKS[cfg.yaml_cfg['task']](cfg)
solver._setup()
solver.eval()
module = solver.ema.module if solver.ema else solver.model
evaluate(module, solver.postprocessor,
solver.val_dataloader, solver.device,args.output_name)
dist_utils.cleanup()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
# priority 0
parser.add_argument('-c', '--config', type=str, required=True)
parser.add_argument('-r', '--resume', type=str, help='resume from checkpoint')
parser.add_argument('-t', '--tuning', type=str, help='tuning from checkpoint')
parser.add_argument('-d', '--device', type=str, help='device',)
parser.add_argument('--seed', type=int, help='exp reproducibility')
parser.add_argument('--output-name', type=str, help='output_name')
# priority 1
parser.add_argument('-u', '--update', nargs='+', help='update yaml config')
# env
parser.add_argument('--print-method', type=str, default='builtin', help='print method')
parser.add_argument('--print-rank', type=int, default=0, help='print rank id')
parser.add_argument('--local-rank', type=int, help='local rank id')
args = parser.parse_args()
main(args)