from enum import Enum
import cv2
class MethodAveragePrecision(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
"""
EveryPointInterpolation = 1
ElevenPointInterpolation = 2
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
def convertToRelativeValues(size, box):
"""Convert absolute box coordinates to relative ones.
Args:
size (tuple of int): (width, height) of the image
box (tuple of int): (X1, X2, Y1, Y2) of the bounding 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
return (x, y, w, h)
def convertToAbsoluteValues(size, box):
"""Convert relative box coordinates to absolute ones.
Args:
size (tuple of int): (width, height) of the image
box (tuple of int): (centerX, centerY, w, h) of the bounding box relative to the image
"""
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