Files
wehub-resource-sync c8a779b1bb
Docker Image CI / build-ubuntu2004 (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:36:55 +08:00

162 lines
5.9 KiB
Python

#
# SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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 os
import sys
import argparse
import numpy as np
import torch
from PIL import Image
from infer import TensorRTInfer
from image_batcher import ImageBatcher
try:
from detectron2.config import get_cfg
from detectron2.data import MetadataCatalog
from detectron2.evaluation import COCOEvaluator
from detectron2.structures import Instances, Boxes, ROIMasks
except ImportError:
print("Could not import Detectron 2 modules. Maybe you did not install Detectron 2")
print(
"Please install Detectron 2, check https://github.com/facebookresearch/detectron2/blob/main/INSTALL.md"
)
sys.exit(1)
def build_evaluator(dataset_name):
"""
Create evaluator for a COCO dataset.
Currently only Mask R-CNN is supported, dataset of interest is COCO, so only COCOEvaluator is implemented.
"""
evaluator_type = MetadataCatalog.get(dataset_name).evaluator_type
if evaluator_type in ["coco"]:
return COCOEvaluator(dataset_name)
else:
raise NotImplementedError("Evaluator type is not supported")
def setup(config_file, weights):
"""
Create config and perform basic setup.
"""
cfg = get_cfg()
cfg.merge_from_file(config_file)
cfg.merge_from_list(["MODEL.WEIGHTS", weights])
cfg.freeze()
return cfg
def main(args):
# Set up Detectron 2 config and build evaluator.
cfg = setup(args.det2_config, args.det2_weights)
dataset_name = cfg.DATASETS.TEST[0]
evaluator = build_evaluator(dataset_name)
evaluator.reset()
trt_infer = TensorRTInfer(args.engine)
batcher = ImageBatcher(
args.input, *trt_infer.input_spec(), config_file=args.det2_config
)
for batch, images, scales in batcher.get_batch():
print(
"Processing Image {} / {}".format(batcher.image_index, batcher.num_images),
end="\r",
)
detections = trt_infer.infer(batch, scales, args.nms_threshold)
for i in range(len(images)):
# Get inference image resolution.
infer_im = Image.open(images[i])
im_width, im_height = infer_im.size
pred_boxes = []
scores = []
pred_classes = []
# Number of detections.
num_instances = len(detections[i])
# Reserve numpy array to hold all mask predictions per image.
pred_masks = np.empty((num_instances, 28, 28), dtype=np.float32)
# Image ID, required for Detectron 2 evaluations.
source_id = int(os.path.splitext(os.path.basename(images[i]))[0])
# Loop over every single detection.
for n in range(num_instances):
det = detections[i][n]
# Append box coordinates data.
pred_boxes.append([det["ymin"], det["xmin"], det["ymax"], det["xmax"]])
# Append score.
scores.append(det["score"])
# Append class.
pred_classes.append(det["class"])
# Append mask.
pred_masks[n] = det["mask"]
# Create new Instances object required for Detectron 2 evalutions and add:
# boxes, scores, pred_classes, pred_masks.
image_shape = (im_height, im_width)
instances = Instances(image_shape)
instances.pred_boxes = Boxes(pred_boxes)
instances.scores = torch.tensor(scores)
instances.pred_classes = torch.tensor(pred_classes)
roi_masks = ROIMasks(torch.tensor(pred_masks))
instances.pred_masks = roi_masks.to_bitmasks(
instances.pred_boxes, im_height, im_width, args.iou_threshold
).tensor
# Process evaluations per image.
image_dict = [{"instances": instances}]
input_dict = [{"image_id": source_id}]
evaluator.process(input_dict, image_dict)
# Final evaluations, generation of mAP accuracy performance.
evaluator.evaluate()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--engine", help="The TensorRT engine to infer with.")
parser.add_argument(
"-i",
"--input",
help="The input to infer, either a single image path, or a directory of images.",
)
parser.add_argument(
"-c",
"--det2_config",
help="The Detectron 2 config file (.yaml) for the model",
type=str,
)
parser.add_argument(
"-w", "--det2_weights", help="The Detectron 2 model weights (.pkl)", type=str
)
parser.add_argument(
"-t",
"--nms_threshold",
type=float,
help="Override the score threshold for the NMS operation, if higher than the threshold in the engine.",
)
parser.add_argument(
"--iou_threshold",
default=0.5,
type=float,
help="Select the IoU threshold for the mask segmentation. Range is 0 to 1. Pixel values more than threshold will become 1, less 0.",
)
args = parser.parse_args()
if not all([args.engine, args.input, args.det2_config, args.det2_weights]):
parser.print_help()
print(
"\nThese arguments are required: --engine --input --det2_config and --det2_weights"
)
sys.exit(1)
main(args)