【问题标题】:how to find overlapping and inner bounding boxes from a outer bounding box?如何从外部边界框中找到重叠和内部边界框?
【发布时间】:2021-04-15 07:05:55
【问题描述】:

我正在尝试注释图像,这是我所做的注释中的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, 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, 138.0], [599.0, 66.0]]},
 {'x': 626,
  'y': 68,
  'width': 295,
  'height': 72,
  'center': [773.5, 104.0],
  'points': [[626.0, 68.0], [626.0, 140.0], [921.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, 140.0], [980.0, 140.0], [980.0, 69.0]]},
 {'x': 1000,
  'y': 72,
  'width': 881,
  'height': 72,
  'center': [1440.5, 108.0],
  'points': [[1000.0, 72.0], [1000.0, 144.0], [1881.0, 144.0], [1881.0, 72.0]]},
 {'x': 1904,
  'y': 73,
  'width': 5,
  'height': 71,
  'center': [1906.5, 108.5],
  'points': [[1904.0, 73.0], [1904.0, 144.0], [1909.0, 144.0], [1909.0, 73.0]]}
 ]

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

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

谁能帮我解决这个问题?

所需的输出:

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

[{'x': 290,
  'y': 66,
  'width': 309,
  'height': 72,
  'center': [444.5, 102.0],
  'points': [[290.0, 66.0], [290.0, 138.0], [599.0, 138.0], [599.0, 66.0]]},
 {'x': 626,
  'y': 68,
  'width': 295,
  'height': 72,
  'center': [773.5, 104.0],
  'points': [[626.0, 68.0], [626.0, 140.0], [921.0, 140.0], [921.0, 68.0]]}]

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

def convert_points(center_x, center_y, width, 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], [x + width / 2, y - height / 2]]

【问题讨论】:

  • 在 C++ 中,您可以使用 opencv Rect 交集(&& 运算符)来测试它们是否重叠。也许还有一个python函数
  • @Micka 如果您遇到任何问题,您可以提供帮助的答案。

标签: python image opencv image-processing bounding-box


【解决方案1】:

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

# 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, tl, br):
            return True;
    
    # check box1 in box2
    tl = box2[0];
    br = box2[2];
    for point in box1:
        if inBounds(point, tl, 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, 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, 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,
 'y': 40.3,
 'height': 116.7,
 'width': 672.7,
 'center': [604.25, 98.65],
 'points': [[267.9, 40.3], [267.9, 157], [940.6, 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, 138.0], [599.0, 66.0]]};

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

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

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

【讨论】:

  • 感谢您的回答。您能解释一下旋转的确切含义吗?我的文档图像始终是直的。
  • by 'not-rotated' 我假设左上角和右上角的 y 值是相同的。右下角和左下角的 y 值同上。你所有的盒子似乎都遵循这个规则,所以我认为你所有的盒子都是平的,这很好。我刚才提到了旋转,因为上面的功能只有在盒子是平的时候才有效。
  • 知道了,另外,我已经尝试了代码,但我得到了TypeError: cannot unpack non-iterable numpy.float64 object,我尝试使用box1 是主框,box2 是其他要比较的框。你能测试一下吗?
  • 你能发布你是如何调用这个函数的吗?请记住:我假设您输入函数的框是这种形式:[左上,右上,右下,左下]。因此,对于您要输入的主框:[[267.9, 40.3], [267.9, 157], [940.6, 157], [940.6, 40.3]]
  • 从你得到的错误来看,我粗略的猜测是错误发生在“x,y = point”行,如果你把整个注释放在box1中,可能会发生这种情况。该函数只需要每个注释的“点”部分。
猜你喜欢
  • 2019-05-11
  • 1970-01-01
  • 2013-02-02
  • 2016-07-06
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 2014-06-30
  • 2014-02-20
相关资源
最近更新 更多