Lingteng Qiu (邱陵腾)
rm assets & wheels
434b0b0
# -*- coding: utf-8 -*-
# @Organization : Tongyi Lab, Alibaba
# @Author : Lingteng Qiu
# @Email : 220019047@link.cuhk.edu.cn
# @Time : 2024-08-30 20:50:27
# @Function : The class defines Bbox
class Bbox:
"""
The class defines Bbox
Args:
box: The box coordinates
mode: The mode of the box
Returns:
Bbox: The Bbox object
"""
def __init__(self, box, mode="whwh"):
"""
Initializes the Bbox object.
Args:
box: The box coordinates
mode: The mode of the box
"""
assert len(box) == 4
assert mode in ["whwh", "xywh"]
self.box = box
self.mode = mode
def to_xywh(self):
"""
Converts the box to xywh mode.
Returns:
Bbox: The Bbox object
"""
if self.mode == "whwh":
l, t, r, b = self.box
center_x = (l + r) / 2
center_y = (t + b) / 2
width = r - l
height = b - t
return Bbox([center_x, center_y, width, height], mode="xywh")
else:
return self
def to_whwh(self):
"""
Converts the box to whwh mode.
Returns:
Bbox: The Bbox object
"""
if self.mode == "whwh":
return self
else:
cx, cy, w, h = self.box
l = cx - w // 2
t = cy - h // 2
r = cx + w - (w // 2)
b = cy + h - (h // 2)
return Bbox([l, t, r, b], mode="whwh")
def area(self):
"""
Calculates the area of the box.
Returns:
float: The area of the box
"""
box = self.to_xywh()
_, __, w, h = box.box
return w * h
def offset(self, offset_w, offset_h):
"""
Offsets the box by the given width and height.
Args:
offset_w: The width offset
offset_h: The height offset
"""
assert self.mode == "whwh"
self.box[0] += offset_w
self.box[1] += offset_h
self.box[2] += offset_w
self.box[3] += offset_h
def get_box(self):
"""
Returns the bounding box as a list of integers.
Returns:
list: The bounding box values as a list of ints
"""
return list(map(int, self.box))
def to_xywh_ratio(self, ori_w, ori_h):
"""
Converts the box to xywh mode and returns the ratio of the box to the original image.
Args:
ori_w: The original width
ori_h: The original height
Returns:
tuple: The ratio of the box to the original image
"""
cx, cy, w, h = self.to_xywh().get_box()
cx = cx / ori_w
cy = cy / ori_h
w = w / ori_w
h = h / ori_h
return cx, cy, w, h
def scale_bbox(self, ori_w, ori_h, new_w, new_h):
"""
Scales the box as the image scale.
Args:
ori_w: The original width
ori_h: The original height
new_w: The new width
new_h: The new height
Returns:
Bbox: The scaled box
"""
assert self.mode == "whwh"
cx, cy, w, h = self.to_xywh_ratio(ori_w, ori_h)
cx = cx * new_w
cy = cy * new_h
w = w * new_w
h = h * new_h
l = cx - w // 2
t = cy - h // 2
r = cx + w - (w // 2)
b = cy + h - (h // 2)
return Bbox([l, t, r, b], mode="whwh")
def scale(self, scale, width, height):
"""
Scales the box with the given scale factor.
Args:
scale: The scale factor
width: The width of the image
height: The height of the image
Returns:
Bbox: The scaled box
"""
new_box = self.to_xywh()
cx, cy, w, h = new_box.get_box()
w = w * scale
h = h * scale
l = cx - w // 2
t = cy - h // 2
r = cx + w - (w // 2)
b = cy + h - (h // 2)
l = int(max(l, 0))
t = int(max(t, 0))
r = int(min(r, width))
b = int(min(b, height))
return Bbox([l, t, r, b], mode="whwh")
def __repr__(self):
box = self.to_whwh()
l, t, r, b = box.box
return f"BBox(left={l}, top={t}, right={r}, bottom={b})"