from enum import Enum import cv2 class CoordinatesType(Enum): """ Class representing if the coordinates are relative to the image size or are absolute values. Developed by: Rafael Padilla Last modification: Apr 28 2018 """ Relative = 1 Absolute = 2 class BBType(Enum): """ Class representing if the bounding box is groundtruth or not. Developed by: Rafael Padilla Last modification: May 24 2018 """ GroundTruth = 1 Detected = 2 class BBFormat(Enum): """ Class representing the format of a bounding box. It can be (X,Y,width,height) => XYWH or (X1,Y1,X2,Y2) => XYX2Y2 Developed by: Rafael Padilla Last modification: May 24 2018 """ XYWH = 1 XYX2Y2 = 2 # size => (width, height) of the image # box => (X1, X2, Y1, Y2) of the bounding box def convertToRelativeValues(size, box): dw = 1. / (size[0]) dh = 1. / (size[1]) cx = (box[1] + box[0]) / 2.0 cy = (box[3] + box[2]) / 2.0 w = box[1] - box[0] h = box[3] - box[2] x = cx * dw y = cy * dh w = w * dw h = h * dh # x,y => (bounding_box_center)/width_of_the_image # w => bounding_box_width / width_of_the_image # h => bounding_box_height / height_of_the_image return (x, y, w, h) # size => (width, height) of the image # box => (centerX, centerY, w, h) of the bounding box relative to the image def convertToAbsoluteValues(size, box): # w_box = round(size[0] * box[2]) # h_box = round(size[1] * box[3]) xIn = round(((2 * float(box[0]) - float(box[2])) * size[0] / 2)) yIn = round(((2 * float(box[1]) - float(box[3])) * size[1] / 2)) xEnd = xIn + round(float(box[2]) * size[0]) yEnd = yIn + round(float(box[3]) * size[1]) if xIn < 0: xIn = 0 if yIn < 0: yIn = 0 if xEnd >= size[0]: xEnd = size[0] - 1 if yEnd >= size[1]: yEnd = size[1] - 1 return (xIn, yIn, xEnd, yEnd) def add_bb_into_image(image, bb, color=(255, 0, 0), thickness=2, label=None): r = int(color[0]) g = int(color[1]) b = int(color[2]) font = cv2.FONT_HERSHEY_SIMPLEX fontScale = 0.5 fontThickness = 1 x1, y1, x2, y2 = bb.getAbsoluteBoundingBox(BBFormat.XYX2Y2) x1 = int(x1) y1 = int(y1) x2 = int(x2) y2 = int(y2) cv2.rectangle(image, (x1, y1), (x2, y2), (b, g, r), thickness) # Add label if label is not None: # Get size of the text box (tw, th) = cv2.getTextSize(label, font, fontScale, fontThickness)[0] # Top-left coord of the textbox (xin_bb, yin_bb) = (x1 + thickness, y1 - th + int(12.5 * fontScale)) # Checking position of the text top-left (outside or inside the bb) if yin_bb - th <= 0: # if outside the image yin_bb = y1 + th # put it inside the bb r_Xin = x1 - int(thickness / 2) r_Yin = y1 - th - int(thickness / 2) # Draw filled rectangle to put the text in it cv2.rectangle(image, (r_Xin, r_Yin - thickness), (r_Xin + tw + thickness * 3, r_Yin + th + int(12.5 * fontScale)), (b, g, r), -1) cv2.putText(image, label, (xin_bb, yin_bb), font, fontScale, (0, 0, 0), fontThickness, cv2.LINE_AA) return image