#!/usr/bin/env python3 # -*- coding:utf-8 -*- # Copyright (c) Megvii Inc. All rights reserved. import cv2 import numpy as np COCO_CLASSES = ("red", "green", "yellow", "empty", "straight", "left", "right", "other") __all__ = ["vis"] def is_nearby(box1, box2, threshold=40): # Compute the centroid of both boxes cx1 = (box1[0] + box1[2]) / 2 cy1 = (box1[1] + box1[3]) / 2 cx2 = (box2[0] + box2[2]) / 2 cy2 = (box2[1] + box2[3]) / 2 # Compute the distance between centroids distance = ((cx1 - cx2) ** 2 + (cy1 - cy2) ** 2) ** 0.5 return distance < threshold def vis(img, boxes, scores, cls_ids, conf, class_names): arrow_offsets = {} seen_boxes = [] for i in range(len(boxes)): box = boxes[i] cls_id = int(cls_ids[i]) score = scores[i] if score < conf: continue x0, y0, x1, y1 = map(int, box) color = (_COLORS[cls_id] * 255).astype(np.uint8).tolist() text = "{}:{:.1f}%".format(class_names[cls_id], score * 100) txt_color = (0, 0, 0) if np.mean(_COLORS[cls_id]) > 0.5 else (255, 255, 255) font = cv2.FONT_HERSHEY_SIMPLEX txt_size = cv2.getTextSize(text, font, 0.4, 1)[0] if cls_id < 4: overlay = img.copy() cv2.rectangle(overlay, (x0, y0), (x1, y1), color, -1) # -1 fills the rectangle alpha = 0.4 # Transparency factor. cv2.addWeighted(overlay, alpha, img, 1 - alpha, 0, img) cv2.rectangle(img, (x0, y0), (x1, y1), color, 2) txt_bk_color = (_COLORS[cls_id] * 255 * 0.7).astype(np.uint8).tolist() cv2.rectangle( img, (x0, y0 + 1), (x0 + txt_size[0] + 1, y0 + int(1.5 * txt_size[1])), txt_bk_color, -1, ) cv2.putText(img, text, (x0, y0 + txt_size[1]), font, 0.4, txt_color, thickness=1) else: nearby_box_idx = None for idx, seen_box in enumerate(seen_boxes): if is_nearby(seen_box, box): nearby_box_idx = idx break offset = 0 if nearby_box_idx is not None: arrow_offsets[nearby_box_idx] = arrow_offsets.get(nearby_box_idx, 0) + 1 offset = arrow_offsets[nearby_box_idx] * (txt_size[1] + 5) else: seen_boxes.append(box) txt_bk_color = (_COLORS[cls_id] * 255 * 0.7).astype(np.uint8).tolist() cv2.rectangle( img, (x0, y1 + 1 + offset), (x0 + txt_size[0] + 1, y1 + int(1.5 * txt_size[1]) + offset), txt_bk_color, -1, ) cv2.putText( img, text, (x0, y1 + txt_size[1] + offset), font, 0.4, txt_color, thickness=1 ) return img _COLORS = np.array( [ # B , G , R 0.000, 0.000, 1.000, 1.000, 0.300, 0.000, 0.000, 1.000, 1.000, 0.494, 0.184, 0.556, 0.466, 0.674, 0.188, 0.301, 0.745, 0.933, 0.635, 0.078, 0.184, 0.300, 0.300, 0.300, 0.600, 0.600, 0.600, 1.000, 0.000, 0.000, 1.000, 0.500, 0.000, 0.749, 0.749, 0.000, 0.000, 1.000, 0.000, 0.000, 0.000, 1.000, 0.667, 0.000, 1.000, 0.333, 0.333, 0.000, 0.333, 0.667, 0.000, 0.333, 1.000, 0.000, 0.667, 0.333, 0.000, 0.667, 0.667, 0.000, 0.667, 1.000, 0.000, 1.000, 0.333, 0.000, 1.000, 0.667, 0.000, 1.000, 1.000, 0.000, 0.000, 0.333, 0.500, 0.000, 0.667, 0.500, 0.000, 1.000, 0.500, 0.333, 0.000, 0.500, 0.333, 0.333, 0.500, 0.333, 0.667, 0.500, 0.333, 1.000, 0.500, 0.667, 0.000, 0.500, 0.667, 0.333, 0.500, 0.667, 0.667, 0.500, 0.667, 1.000, 0.500, 1.000, 0.000, 0.500, 1.000, 0.333, 0.500, 1.000, 0.667, 0.500, 1.000, 1.000, 0.500, 0.000, 0.333, 1.000, 0.000, 0.667, 1.000, 0.000, 1.000, 1.000, 0.333, 0.000, 1.000, 0.333, 0.333, 1.000, 0.333, 0.667, 1.000, 0.333, 1.000, 1.000, 0.667, 0.000, 1.000, 0.667, 0.333, 1.000, 0.667, 0.667, 1.000, 0.667, 1.000, 1.000, 1.000, 0.000, 1.000, 1.000, 0.333, 1.000, 1.000, 0.667, 1.000, 0.333, 0.000, 0.000, 0.500, 0.000, 0.000, 0.667, 0.000, 0.000, 0.833, 0.000, 0.000, 1.000, 0.000, 0.000, 0.000, 0.167, 0.000, 0.000, 0.333, 0.000, 0.000, 0.500, 0.000, 0.000, 0.667, 0.000, 0.000, 0.833, 0.000, 0.000, 1.000, 0.000, 0.000, 0.000, 0.167, 0.000, 0.000, 0.333, 0.000, 0.000, 0.500, 0.000, 0.000, 0.667, 0.000, 0.000, 0.833, 0.000, 0.000, 1.000, 0.000, 0.000, 0.000, 0.143, 0.143, 0.143, 0.286, 0.286, 0.286, 0.429, 0.429, 0.429, 0.571, 0.571, 0.571, 0.714, 0.714, 0.714, 0.857, 0.857, 0.857, 0.000, 0.447, 0.741, 0.314, 0.717, 0.741, 0.50, 0.5, 0 ] ).astype(np.float32).reshape(-1, 3)