import numpy as np import cv2 from math import sqrt _LINE_THICKNESS_SCALING = 500.0 np.random.seed(69) RAND_COLORS = np.random.randint(10, 255, (80, 3), "int") # used for class visu def render_box(img, box, color=(200, 200, 200)): """ Render a box. Calculates scaling and thickness automatically. :param img: image to render into :param box: (x1, y1, x2, y2) - box coordinates :param color: (b, g, r) - box color :return: updated image """ x1, y1, x2, y2 = box thickness = int( round( (img.shape[0] * img.shape[1]) / (_LINE_THICKNESS_SCALING * _LINE_THICKNESS_SCALING) ) ) thickness = max(1, thickness) img = cv2.rectangle( img, (int(x1), int(y1)), (int(x2), int(y2)), color, thickness=thickness ) return img def render_filled_box(img, box, color=(200, 200, 200)): """ Render a box. Calculates scaling and thickness automatically. :param img: image to render into :param box: (x1, y1, x2, y2) - box coordinates :param color: (b, g, r) - box color :return: updated image """ x1, y1, x2, y2 = box img = cv2.rectangle( img, (int(x1), int(y1)), (int(x2), int(y2)), color, thickness=cv2.FILLED ) return img _TEXT_THICKNESS_SCALING = 700.0 _TEXT_SCALING = 520.0 def get_text_size(img, text, normalised_scaling=1.0): """ Get calculated text size (as box width and height) :param img: image reference, used to determine appropriate text scaling :param text: text to display :param normalised_scaling: additional normalised scaling. Default 1.0. :return: (width, height) - width and height of text box """ thickness = int( round( (img.shape[0] * img.shape[1]) / (_TEXT_THICKNESS_SCALING * _TEXT_THICKNESS_SCALING) ) * normalised_scaling ) thickness = max(1, thickness) scaling = img.shape[0] / _TEXT_SCALING * normalised_scaling return cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, scaling, thickness)[0] def render_text(img, text, pos, color=(200, 200, 200), normalised_scaling=1.0): """ Render a text into the image. Calculates scaling and thickness automatically. :param img: image to render into :param text: text to display :param pos: (x, y) - upper left coordinates of render position :param color: (b, g, r) - text color :param normalised_scaling: additional normalised scaling. Default 1.0. :return: updated image """ x, y = pos thickness = int( round( (img.shape[0] * img.shape[1]) / (_TEXT_THICKNESS_SCALING * _TEXT_THICKNESS_SCALING) ) * normalised_scaling ) thickness = max(2, thickness) scaling = img.shape[0] / _TEXT_SCALING * normalised_scaling size = get_text_size(img, text, normalised_scaling) cv2.putText( img, text, (int(x), int(y + size[1])), cv2.FONT_HERSHEY_SIMPLEX, scaling, color, thickness=thickness, ) return img def plot_one_box(x, img, color=None, label=None, line_thickness=None): """ description: Plots one bounding box on image img, this function comes from YoLov5 project. param: x: a box likes [x1,y1,x2,y2] img: a opencv image object color: color to draw rectangle, such as (0,255,0) label: str line_thickness: int return: no return """ tl = ( line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 ) # line/font thickness if color == None: color = [np.random.randint(0, 255) for _ in range(3)] c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3])) cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA) if label: tf = max(tl - 1, 1) # font thickness t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0] c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled cv2.putText( img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA, )