| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- # copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
- #
- # 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
|