|
|
|
|
@ -7,22 +7,33 @@ def adjust_bboxes_to_image_border(boxes, image_shape, threshold=20):
|
|
|
|
|
"""
|
|
|
|
|
Adjust bounding boxes to stick to image border if they are within a certain threshold.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
boxes (torch.Tensor): (n, 4)
|
|
|
|
|
image_shape (tuple): (height, width)
|
|
|
|
|
threshold (int): pixel threshold
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
adjusted_boxes (torch.Tensor): adjusted bounding boxes
|
|
|
|
|
函数功能:
|
|
|
|
|
该函数用于调整边界框(bounding boxes)的坐标,使其在距离图像边界小于指定阈值时,能够紧贴图像的边界。
|
|
|
|
|
|
|
|
|
|
参数说明:
|
|
|
|
|
boxes (torch.Tensor): (n, 4)
|
|
|
|
|
- 输入的边界框张量,形状为 (n, 4),其中 n 表示边界框的数量,每个边界框由 4 个值表示,
|
|
|
|
|
通常分别对应左上角的 x 坐标、左上角的 y 坐标、右下角的 x 坐标、右下角的 y 坐标。
|
|
|
|
|
image_shape (tuple): (height, width)
|
|
|
|
|
- 图像的形状,以元组形式表示,包含图像的高度(height)和宽度(width)两个维度的尺寸信息。
|
|
|
|
|
threshold (int): pixel threshold
|
|
|
|
|
- 像素阈值,用于判断边界框是否需要调整紧贴图像边界,单位为像素,默认值为 20。
|
|
|
|
|
|
|
|
|
|
返回值:
|
|
|
|
|
adjusted_boxes (torch.Tensor): adjusted bounding boxes
|
|
|
|
|
- 返回调整后的边界框张量,其格式和输入的 'boxes' 张量一致,只是坐标值根据规则进行了相应调整。
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# Image dimensions
|
|
|
|
|
# 获取图像的高度和宽度,分别赋值给变量 h 和 w,用于后续边界框坐标调整的判断依据
|
|
|
|
|
h, w = image_shape
|
|
|
|
|
|
|
|
|
|
# Adjust boxes
|
|
|
|
|
# 调整边界框的坐标,如果边界框的左上角 x 坐标(boxes[:, 0])小于阈值,将其设置为 0,使其紧贴图像左边界
|
|
|
|
|
boxes[boxes[:, 0] < threshold, 0] = 0 # x1
|
|
|
|
|
# 如果边界框的左上角 y 坐标(boxes[:, 1])小于阈值,将其设置为 0,使其紧贴图像上边界
|
|
|
|
|
boxes[boxes[:, 1] < threshold, 1] = 0 # y1
|
|
|
|
|
# 如果边界框的右下角 x 坐标(boxes[:, 2])大于图像宽度减去阈值,将其设置为图像宽度 w,使其紧贴图像右边界
|
|
|
|
|
boxes[boxes[:, 2] > w - threshold, 2] = w # x2
|
|
|
|
|
# 如果边界框的右下角 y 坐标(boxes[:, 3])大于图像高度减去阈值,将其设置为图像高度 h,使其紧贴图像下边界
|
|
|
|
|
boxes[boxes[:, 3] > h - threshold, 3] = h # y2
|
|
|
|
|
return boxes
|
|
|
|
|
|
|
|
|
|
@ -31,34 +42,55 @@ def bbox_iou(box1, boxes, iou_thres=0.9, image_shape=(640, 640), raw_output=Fals
|
|
|
|
|
"""
|
|
|
|
|
Compute the Intersection-Over-Union of a bounding box with respect to an array of other bounding boxes.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
box1 (torch.Tensor): (4, )
|
|
|
|
|
boxes (torch.Tensor): (n, 4)
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
high_iou_indices (torch.Tensor): Indices of boxes with IoU > thres
|
|
|
|
|
函数功能:
|
|
|
|
|
该函数用于计算一个给定的边界框(box1)与一组其他边界框(boxes)之间的交并比(Intersection-Over-Union,简称 IoU),
|
|
|
|
|
并可以根据设定的 IoU 阈值筛选出满足条件的边界框索引。
|
|
|
|
|
|
|
|
|
|
参数说明:
|
|
|
|
|
box1 (torch.Tensor): (4, )
|
|
|
|
|
- 单个边界框的坐标张量,形状为 (4, ),4 个值依次代表左上角的 x 坐标、左上角的 y 坐标、右下角的 x 坐标、右下角的 y 坐标。
|
|
|
|
|
boxes (torch.Tensor): (n, 4)
|
|
|
|
|
- 一组边界框的坐标张量,形状为 (n, 4),n 表示边界框的数量,每个边界框的坐标表示方式同 box1。
|
|
|
|
|
iou_thres (int, optional): 交并比阈值,默认值为 0.9,用于筛选出与给定边界框 IoU 大于此阈值的其他边界框。
|
|
|
|
|
image_shape (tuple, optional): (height, width),图像的形状,默认值为 (640, 640),用于在计算 IoU 前调整边界框坐标(调用了 adjust_bboxes_to_image_border 函数)。
|
|
|
|
|
raw_output (bool, optional): 是否返回原始的 IoU 值,默认值为 False,如果为 True,则直接返回计算得到的 IoU 值(或 0,如果没有交集情况),
|
|
|
|
|
如果为 False,则返回 IoU 大于阈值的边界框索引。
|
|
|
|
|
|
|
|
|
|
返回值:
|
|
|
|
|
如果 raw_output 为 True:
|
|
|
|
|
返回计算得到的交并比(IoU)值,如果输入的 boxes 张量为空(即 iou.numel() == 0,表示没有其他边界框与之计算 IoU),则返回 0。
|
|
|
|
|
如果 raw_output 为 False:
|
|
|
|
|
返回满足 IoU 大于阈值(iou_thres)条件的边界框在输入的 boxes 张量中的索引,以扁平化后的张量形式返回。
|
|
|
|
|
"""
|
|
|
|
|
# 先调用 adjust_bboxes_to_image_border 函数,根据图像形状和阈值调整输入的边界框(boxes)坐标,使其紧贴图像边界
|
|
|
|
|
boxes = adjust_bboxes_to_image_border(boxes, image_shape)
|
|
|
|
|
# obtain coordinates for intersections
|
|
|
|
|
# 以下是计算交并比(IoU)的步骤:
|
|
|
|
|
|
|
|
|
|
# 对于每个边界框,获取其与给定边界框(box1)在 x 方向上的交集的起始坐标(取两者左上角 x 坐标的最大值)
|
|
|
|
|
x1 = torch.max(box1[0], boxes[:, 0])
|
|
|
|
|
# 获取其与给定边界框在 y 方向上的交集的起始坐标(取两者左上角 y 坐标的最大值)
|
|
|
|
|
y1 = torch.max(box1[1], boxes[:, 1])
|
|
|
|
|
x2 = torch.min(box1[2], boxes[:, 2])
|
|
|
|
|
y2 = torch.min(box1[3], boxes[:, 3])
|
|
|
|
|
# 获取其与给定边界框在 x 方向上的交集的结束坐标(取两者右下角 x 坐标的最小值)
|
|
|
|
|
x2 = torch.max(box1[2], boxes[:, 2])
|
|
|
|
|
# 获取其与给定边界框在 y 方向上的交集的结束坐标(取两者右下角 y 坐标的最小值)
|
|
|
|
|
y2 = torch.max(box1[3], boxes[:, 3])
|
|
|
|
|
|
|
|
|
|
# compute the area of intersection
|
|
|
|
|
# 计算交集区域的面积,通过计算交集区域在 x 和 y 方向上的边长(需要使用 clamp(0) 确保边长非负),然后相乘得到面积
|
|
|
|
|
intersection = (x2 - x1).clamp(0) * (y2 - y1).clamp(0)
|
|
|
|
|
|
|
|
|
|
# compute the area of both individual boxes
|
|
|
|
|
# 计算给定边界框(box1)的面积,通过右下角坐标与左上角坐标差值相乘得到
|
|
|
|
|
box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
|
|
|
|
|
# 计算输入的一组边界框(boxes)中每个边界框的面积,同样通过右下角坐标与左上角坐标差值相乘得到
|
|
|
|
|
box2_area = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
|
|
|
|
|
|
|
|
|
|
# compute the area of union
|
|
|
|
|
# 计算并集区域的面积,通过两个边界框面积之和减去交集区域面积得到
|
|
|
|
|
union = box1_area + box2_area - intersection
|
|
|
|
|
|
|
|
|
|
# compute the IoU
|
|
|
|
|
# 计算交并比(IoU),即交集区域面积除以并集区域面积,得到的结果形状应该为 (n, ),n 为输入的边界框数量(boxes 的行数)
|
|
|
|
|
iou = intersection / union # Should be shape (n, )
|
|
|
|
|
if raw_output:
|
|
|
|
|
return 0 if iou.numel() == 0 else iou
|
|
|
|
|
|
|
|
|
|
# return indices of boxes with IoU > thres
|
|
|
|
|
return torch.nonzero(iou > iou_thres).flatten()
|
|
|
|
|
# 根据设定的 IoU 阈值(iou_thres),筛选出 IoU 大于该阈值的边界框索引,通过 torch.nonzero 找到满足条件的位置索引,
|
|
|
|
|
# 并使用 flatten 方法将其扁平化,最终返回这些满足条件的边界框在输入的 boxes 张量中的索引
|
|
|
|
|
return torch.nonzero(iou > iou_thres).flatten()
|