Created
January 24, 2018 08:08
-
-
Save lekhanh1234/7469a31e73f3a8e6737ebcef0d936970 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import collections | |
| import PIL.Image as Image | |
| import PIL.ImageDraw as ImageDraw | |
| import PIL.ImageFont as ImageFont | |
| import numpy as np | |
| from object_detection.utils.visualization_utils import STANDARD_COLORS | |
| def visualize_boxes_and_labels_on_image_array(image, | |
| boxes, | |
| classes, | |
| scores, | |
| category_index, | |
| instance_masks=None, | |
| keypoints=None, | |
| use_normalized_coordinates=False, | |
| max_boxes_to_draw=20, | |
| min_score_thresh=.5, | |
| agnostic_mode=False, | |
| line_thickness=4): | |
| """Overlay labeled boxes on an image with formatted scores and label names. | |
| This function groups boxes that correspond to the same location | |
| and creates a display string for each detection and overlays these | |
| on the image. Note that this function modifies the image in place, and returns | |
| that same image. | |
| Args: | |
| image: uint8 numpy array with shape (img_height, img_width, 3) | |
| boxes: a numpy array of shape [N, 4] | |
| classes: a numpy array of shape [N]. Note that class indices are 1-based, | |
| and match the keys in the label map. | |
| scores: a numpy array of shape [N] or None. If scores=None, then | |
| this function assumes that the boxes to be plotted are groundtruth | |
| boxes and plot all boxes as black with no classes or scores. | |
| category_index: a dict containing category dictionaries (each holding | |
| category index `id` and category name `name`) keyed by category indices. | |
| instance_masks: a numpy array of shape [N, image_height, image_width], can | |
| be None | |
| keypoints: a numpy array of shape [N, num_keypoints, 2], can | |
| be None | |
| use_normalized_coordinates: whether boxes is to be interpreted as | |
| normalized coordinates or not. | |
| max_boxes_to_draw: maximum number of boxes to visualize. If None, draw | |
| all boxes. | |
| min_score_thresh: minimum score threshold for a box to be visualized | |
| agnostic_mode: boolean (default: False) controlling whether to evaluate in | |
| class-agnostic mode or not. This mode will display scores but ignore | |
| classes. | |
| line_thickness: integer (default: 4) controlling line width of the boxes. | |
| Returns: | |
| uint8 numpy array with shape (img_height, img_width, 3) with overlaid boxes. | |
| """ | |
| # Create a display string (and color) for every box location, group any boxes | |
| # that correspond to the same location. | |
| box_to_display_str_map = collections.defaultdict(list) | |
| box_to_color_map = collections.defaultdict(str) | |
| if not max_boxes_to_draw: | |
| max_boxes_to_draw = boxes.shape[0] | |
| for i in range(min(max_boxes_to_draw, boxes.shape[0])): | |
| if scores is None or scores[i] > min_score_thresh: | |
| box = tuple(boxes[i]) | |
| class_name = category_index[classes[i]]['name'] | |
| display_str = '{}: {}%'.format( | |
| class_name, | |
| int(100 * scores[i])) | |
| box_to_display_str_map[box].append(display_str) | |
| box_to_color_map[box] = STANDARD_COLORS[ | |
| classes[i] % len(STANDARD_COLORS)] | |
| # Draw all boxes onto image. | |
| for box, color in box_to_color_map.items(): | |
| ymin, xmin, ymax, xmax = box | |
| draw_bounding_box_on_image_array( | |
| image, | |
| ymin, | |
| xmin, | |
| ymax, | |
| xmax, | |
| color=color, | |
| thickness=line_thickness, | |
| display_str_list=box_to_display_str_map[box], | |
| use_normalized_coordinates=use_normalized_coordinates) | |
| return image | |
| def draw_bounding_box_on_image_array(image, | |
| ymin, | |
| xmin, | |
| ymax, | |
| xmax, | |
| color='red', | |
| thickness=4, | |
| display_str_list=(), | |
| use_normalized_coordinates=True): | |
| """Adds a bounding box to an image (numpy array). | |
| Args: | |
| image: a numpy array with shape [height, width, 3]. | |
| ymin: ymin of bounding box in normalized coordinates (same below). | |
| xmin: xmin of bounding box. | |
| ymax: ymax of bounding box. | |
| xmax: xmax of bounding box. | |
| color: color to draw bounding box. Default is red. | |
| thickness: line thickness. Default value is 4. | |
| display_str_list: list of strings to display in box | |
| (each to be shown on its own line). | |
| use_normalized_coordinates: If True (default), treat coordinates | |
| ymin, xmin, ymax, xmax as relative to the image. Otherwise treat | |
| coordinates as absolute. | |
| """ | |
| image_pil = Image.fromarray(np.uint8(image)).convert('RGB') | |
| draw_bounding_box_on_image(image_pil, ymin, xmin, ymax, xmax, color, | |
| thickness, display_str_list, | |
| use_normalized_coordinates) | |
| np.copyto(image, np.array(image_pil)) | |
| def draw_bounding_box_on_image(image, | |
| ymin, | |
| xmin, | |
| ymax, | |
| xmax, | |
| color='red', | |
| thickness=4, | |
| display_str_list=(), | |
| use_normalized_coordinates=True): | |
| """Adds a bounding box to an image. | |
| Each string in display_str_list is displayed on a separate line 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 strings | |
| are displayed below the bounding box. | |
| Args: | |
| image: a PIL.Image object. | |
| ymin: ymin of bounding box. | |
| xmin: xmin of bounding box. | |
| ymax: ymax of bounding box. | |
| xmax: xmax of bounding box. | |
| color: color to draw bounding box. Default is red. | |
| thickness: line thickness. Default value is 4. | |
| display_str_list: list of strings to display in box | |
| (each to be shown on its own line). | |
| use_normalized_coordinates: If True (default), 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=color) | |
| try: | |
| font = ImageFont.truetype('UbuntuMono-BI.ttf', 32) | |
| except IOError: | |
| font = ImageFont.load_default() | |
| # If the total height of the display strings added to the top of the bounding | |
| # box exceeds the top of the image, stack the strings below the bounding box | |
| # instead of above. | |
| display_str_heights = [font.getsize(ds)[1] for ds in display_str_list] | |
| # Each display_str has a top and bottom margin of 0.05x. | |
| total_display_str_height = (1 + 2 * 0.05) * sum(display_str_heights) | |
| if top > total_display_str_height: | |
| text_bottom = top | |
| else: | |
| text_bottom = bottom + total_display_str_height | |
| # Reverse list and print from bottom to top. | |
| for display_str in display_str_list[::-1]: | |
| 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=color) | |
| draw.text( | |
| (left + margin, text_bottom - text_height - margin), | |
| display_str, | |
| fill='black', | |
| font=font) | |
| text_bottom -= text_height - 2 * margin |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
item {
id: 1
name: 'stop'
}
item {
id: 2
name: 'no_entry'
}
item {
id: 3
name: 'no_turn_left'
}
item {
id: 4
name: 'no_turn_right'
}
item {
id: 5
name: 'maximum_speed'
}
item {
id: 6
name: 'turn_left_ahead'
}
item {
id: 7
name: 'turn_right_ahead'
}
item {
id: 8
name: 'minimum_speed'
}
item {
id: 9
name: 'minimum_speed_end'
}
item {
id: 10
name: 'restriction_end'
}
item {
id: 11
name: 'turn_left'
}
item {
id: 12
name: 'turn_right'
}