如何从外边界框找到重叠和内边界框?

问题描述

我正在尝试对图像进行注释,这是我所做注释中的 one 边界框详细信息,

Original Image - 注释基于此文档图像。

# annotation
{'x': 267.9,'y': 40.3,'height': 116.7,'width': 672.7,'center': [604.25,98.65],'points': [[267.9,40.3],[267.9,157],[940.6,40.3]]}

现在我还有另外五个小边界框,它们也是我注释的,

[{'x': 290,'y': 66,'width': 309,'height': 72,'center': [444.5,102.0],'points': [[290.0,66.0],[290.0,138.0],[599.0,66.0]]},{'x': 626,'y': 68,'width': 295,'center': [773.5,104.0],'points': [[626.0,68.0],[626.0,140.0],[921.0,68.0]]},{'x': 960,'y': 69,'width': 20,'height': 71,'center': [970.0,104.5],'points': [[960.0,69.0],[960.0,[980.0,69.0]]},{'x': 1000,'y': 72,'width': 881,'center': [1440.5,108.0],'points': [[1000.0,72.0],[1000.0,144.0],[1881.0,72.0]]},{'x': 1904,'y': 73,'width': 5,'center': [1906.5,108.5],'points': [[1904.0,73.0],[1904.0,[1909.0,73.0]]}
 ]

我正在寻找一种方法来找出上述 5 个边界框坐标中有多少重叠或进入我位于最顶部的第一个主边界框内。

我还需要一个选项来选择重叠的百分比以将其视为重叠。假设两个盒子稍微接触,我不想要它们。至少有 10-15% 的 bBox 应该是 Insider 来考虑它重叠或内部。

谁能帮助我了解如何实现这一目标?

期望输出

在我的示例中,下面的这两个较小的边界框位于主边界框的内部或与其重叠。

[{'x': 290,68.0]]}]

我用来为 points 的边界框创建 center points,width,height函数是这样的,

def convert_points(center_x,center_y,height):
    x = center_x
    y = center_y
    return [[x - width / 2,y - height / 2],[x - width / 2,y + height / 2],[x + width / 2,y - height / 2]]

解决方法

您可以通过检查一个框的任何角是否落在另一个框的边界内来检查两个框是否有重叠(反之亦然)。

# check if a point falls within bounds
def inBounds(point,tl,br):
    x,y = point;
    left,top = tl;
    right,bottom = br;
    if left < x and x < right and top < y and y < bottom:
        return True;
    return False;

# check if these two boxes have any overlap
def boxOverlap(box1,box2):
    # check box2 in box1
    tl = box1[0];
    br = box1[2];
    for point in box2:
        if inBounds(point,br):
            return True;
    
    # check box1 in box2
    tl = box2[0];
    br = box2[2];
    for point in box1:
        if inBounds(point,br):
            return True;

    # no overlap
    return False;

编辑:

抱歉,澄清一下:我将框视为四个点 [左上角、右上角、右下角、左下角],并且我认为这些框没有旋转或任何其他东西(我认为这是一个大多数注释的安全假设)。

编辑 2:

这是一个如何使用它的示例。请记住:我不知道您将使用它的所有不同方式。如果您发现某些内容不起作用,则必须对其进行修改以供您自己使用。

# main box annotation
main_annot = {'x': 267.9,'y': 40.3,'height': 116.7,'width': 672.7,'center': [604.25,98.65],'points': [[267.9,40.3],[267.9,157],[940.6,40.3]]};

# other box annotation
other_annot = {'x': 290,'y': 66,'width': 309,'height': 72,'center': [444.5,102.0],'points': [[290.0,66.0],[290.0,138.0],[599.0,66.0]]};

if boxOverlap(main_annot['points'],other_annot['points']):
    print("OVERLAP DETECTED");
else:
    print("NO OVERLAP");

编辑 3:

哇!我刚刚想到了这个功能不起作用的情况。请暂时忽略此答案。我今天没有太多时间来处理这个问题。如果我稍后想出另一个答案,我会发布它,但现在你不应该使用它。抱歉,我应该更努力地检查边缘情况。

编辑 4:

好的,这次我查找了一个实际的算法,而不是试图在现场制作一个。

# check if these two boxes have any overlap
def boxOverlap(box1,box2):
    # get corners
    tl1 = box1[0];
    br1 = box1[2];
    tl2 = box2[0];
    br2 = box2[2];

    # separating axis theorem
    # left/right
    if tl1[0] >= br2[0] or tl2[0] >= br1[0]:
        return False;

    # top/down
    if tl1[1] >= br2[1] or tl2[1] >= br1[1]:
        return False;

    # overlap
    return True;

# main box annotation
main_annot = {'x': 267.9,other_annot['points']):
    print("OVERLAP DETECTED");
else:
    print("NO OVERLAP");

这是我从 https://www.geeksforgeeks.org/find-two-rectangles-overlap/ 中提取等式的来源

那太尴尬了,我应该从一开始就使用一个既定的算法。