Files
FastDeploy/python/fastdeploy/vision/evaluation/detection.py
WJJ1995 e8b22283c9 [Other] Support batch eval for detection (#587)
* add onnx_ort_runtime demo

* rm in requirements

* support batch eval
2022-11-14 21:33:33 +08:00

114 lines
4.5 KiB
Python

# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
import copy
import collections
import math
def eval_detection(model,
data_dir,
ann_file,
conf_threshold=None,
nms_iou_threshold=None,
plot=False,
batch_size=1):
from .utils import CocoDetection
from .utils import COCOMetric
import cv2
from tqdm import trange
import time
if conf_threshold is not None or nms_iou_threshold is not None:
assert conf_threshold is not None and nms_iou_threshold is not None, "The conf_threshold and nms_iou_threshold should be setted at the same time"
assert isinstance(conf_threshold, (
float,
int)), "The conf_threshold:{} need to be int or float".format(
conf_threshold)
assert isinstance(nms_iou_threshold, (
float,
int)), "The nms_iou_threshold:{} need to be int or float".format(
nms_iou_threshold)
eval_dataset = CocoDetection(
data_dir=data_dir, ann_file=ann_file, shuffle=False)
all_image_info = eval_dataset.file_list
image_num = eval_dataset.num_samples
eval_dataset.data_fields = {
'im_id', 'image_shape', 'image', 'gt_bbox', 'gt_class', 'is_crowd'
}
eval_metric = COCOMetric(
coco_gt=copy.deepcopy(eval_dataset.coco_gt), classwise=False)
scores = collections.OrderedDict()
twenty_percent_image_num = math.ceil(image_num * 0.2)
start_time = 0
end_time = 0
average_inference_time = 0
im_list = list()
im_id_list = list()
for image_info, i in zip(all_image_info,
trange(
image_num, desc="Inference Progress")):
if i == twenty_percent_image_num:
start_time = time.time()
im = cv2.imread(image_info["image"])
im_id = image_info["im_id"]
if batch_size == 1:
if conf_threshold is None and nms_iou_threshold is None:
result = model.predict(im.copy())
else:
result = model.predict(im, conf_threshold, nms_iou_threshold)
pred = {
'bbox': [[c] + [s] + b
for b, s, c in zip(result.boxes, result.scores,
result.label_ids)],
'bbox_num': len(result.boxes),
'im_id': im_id
}
eval_metric.update(im_id, pred)
else:
im_list.append(im)
im_id_list.append(im_id)
# If the batch_size is not satisfied, the remaining pictures are formed into a batch
if (i + 1) % batch_size != 0 and i != image_num - 1:
continue
if conf_threshold is None and nms_iou_threshold is None:
results = model.batch_predict(im_list)
else:
model.postprocessor.conf_threshold = conf_threshold
model.postprocessor.nms_threshold = nms_iou_threshold
results = model.batch_predict(im_list)
for k in range(len(im_list)):
pred = {
'bbox': [[c] + [s] + b
for b, s, c in zip(results[k].boxes, results[
k].scores, results[k].label_ids)],
'bbox_num': len(results[k].boxes),
'im_id': im_id_list[k]
}
eval_metric.update(im_id_list[k], pred)
im_list.clear()
im_id_list.clear()
if i == image_num - 1:
end_time = time.time()
average_inference_time = round(
(end_time - start_time) / (image_num - twenty_percent_image_num), 4)
eval_metric.accumulate()
eval_details = eval_metric.details
scores.update(eval_metric.get())
scores.update({'average_inference_time(s)': average_inference_time})
eval_metric.reset()
return scores