Files
Rajeev Rao d7baf010e4 TensorRT OSS 21.02 release
Signed-off-by: Rajeev Rao <rajeevrao@nvidia.com>
2021-02-05 14:22:04 -08:00

121 lines
4.8 KiB
Python

#
# Copyright (c) 2021, NVIDIA CORPORATION. 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.
#
# Utility functions for drawing bounding boxes on PIL images
import numpy as np
import PIL.ImageDraw as ImageDraw
import PIL.ImageFont as ImageFont
def draw_bounding_boxes_on_image(image,
boxes,
color=(255, 0, 0),
thickness=4,
display_str_list=()):
"""Draws bounding boxes on image.
Args:
image (PIL.Image): PIL.Image object
boxes (np.array): a 2 dimensional numpy array
of [N, 4]: (ymin, xmin, ymax, xmax)
The coordinates are in normalized format between [0, 1]
color (int, int, int): RGB tuple describing color to draw bounding box
thickness (int): bounding box line thickness
display_str_list [str]: list of strings.
Contains one string for each bounding box.
Raises:
ValueError: if boxes is not a [N, 4] array
"""
boxes_shape = boxes.shape
if not boxes_shape:
return
if len(boxes_shape) != 2 or boxes_shape[1] != 4:
raise ValueError('boxes must be of size [N, 4]')
for i in range(boxes_shape[0]):
draw_bounding_box_on_image(image, boxes[i, 0], boxes[i, 1], boxes[i, 2],
boxes[i, 3], color, thickness, display_str_list[i])
def draw_bounding_box_on_image(image,
ymin,
xmin,
ymax,
xmax,
color=(255, 0, 0),
thickness=4,
display_str='',
use_normalized_coordinates=True):
"""Adds a bounding box to an image.
Bounding box coordinates can be specified in either absolute (pixel) or
normalized coordinates by setting the use_normalized_coordinates argument.
The string passed in display_str is displayed above the
bounding box in black text on a rectangle filled with the input 'color'.
If the top of the bounding box extends to the edge of the image, the string
is displayed below the bounding box.
Args:
image (PIL.Image): PIL.Image object
ymin (float): ymin of bounding box
xmin (float): xmin of bounding box
ymax (float): ymax of bounding box
xmax (float): xmax of bounding box
color (int, int, int): RGB tuple describing color to draw bounding box
thickness (int): line thickness
display_str (str): string to display in box
use_normalized_coordinates (bool): If True, treat coordinates
ymin, xmin, ymax, xmax as relative to the image. Otherwise treat
coordinates as absolute
"""
draw = ImageDraw.Draw(image)
im_width, im_height = image.size
if use_normalized_coordinates:
(left, right, top, bottom) = (xmin * im_width, xmax * im_width,
ymin * im_height, ymax * im_height)
else:
(left, right, top, bottom) = (xmin, xmax, ymin, ymax)
draw.line([(left, top), (left, bottom), (right, bottom),
(right, top), (left, top)], width=thickness, fill=tuple(color))
try:
font = ImageFont.truetype('arial.ttf', 24)
except IOError:
font = ImageFont.load_default()
# If the total height of the display string added to the top of the bounding
# box exceeds the top of the image, move the string below the bounding box
# instead of above
display_str_height = font.getsize(display_str)[1]
# Each display_str has a top and bottom margin of 0.05x
total_display_str_height = (1 + 2 * 0.05) * display_str_height
if top > total_display_str_height:
text_bottom = top
else:
text_bottom = bottom + total_display_str_height
text_width, text_height = font.getsize(display_str)
margin = np.ceil(0.05 * text_height)
draw.rectangle(
[(left, text_bottom - text_height - 2 * margin), (left + text_width,
text_bottom)],
fill=tuple(color))
draw.text(
(left + margin, text_bottom - text_height - margin),
display_str,
fill='black',
font=font)
text_bottom -= text_height - 2 * margin