繁体   English   中英

给定一个矩形列表,如何找到完全包含在其他矩形中的所有矩形?

[英]Given a list of rectangles, how to find all rectangles that are fully contained within other ones?

我有一个计算机视觉算法,可以在检测到的对象周围放置边界框。 边界框列表如下:

bounding_boxes = [[x, y, w, h], [x2, y2, w2, h2], ...]

其中 x 和 y 是左上角的坐标,h 和 w 是框的高度和宽度。 但是,我对完全包含在任何其他较大盒子中的盒子不感兴趣。 检测这些的有效方法是什么?

正如您在问题下的评论中确认的那样,您需要识别并删除包含在单个其他框中的框。 如果一个盒子包含在其他盒子的联合中,但没有其他单个盒子包含它,那么它不应该被删除(例如在boxes = [[0, 0, 2, 4], [1, 1, 3, 3], [2, 0, 4, 4]] ,第二个框包含在第一个和第三个的并集中,但不应删除)。


此任务的天真(蛮力)算法非常简单。 这是伪代码:

for i in [0, 1, ..., n]:
    for j in [i+1, i+2, ..., n]:
        check if box[i] contains in box[j] and otherwise.

这个算法的复杂度显然是O(n^2) 这种算法很容易实现,如果box的数量很少(100-500左右,如果你不需要视频处理的实时性能,甚至1000)推荐使用。


快速算法的复杂度是O(n log n) ,我相信这也是这个问题的最小理论复杂度。 形式上,所需的算法采用以下输入并返回以下 output:

Input: boxes[] - Array of n Rectangles, Tuples of (x1, y1, x2, y2), where 
                 (x1, y1) is coordinates of the left bottom corner, (x2, y2)
                 is the coordinates of the top right corner.
Output: inner_boxes[] - Array of Rectangles that should be removed.

快速算法的伪代码:

1) Allocate an Array events[] with the length 2*n, the elements of which are 
   Tuples (y, corresponding_box_index, event). 

2) For i in [0, 1, ..., n]:
     events[2 * i    ] = Tuple(boxes[i].y1, i, 'push')
     events[2 * i + 1] = Tuple(boxes[i].y2, i, 'pop')

3) Sort events[] by the ascending of y coordinate (from smaller to larger).
   If there are equal y coordinates, Then:
   - Tuples with 'pop' event are smaller thant Tuples with 'push' event.
   - If two Tuples has the same event, they are sorted by the ascending of
     the width of their corresponding boxes.

4) Create a Map cross_section_map[], that maps a Key (Value) x to a Tuple
   (corresponding_box_index, type), where type can be either 'left' or 'right'.
   Make sure that the 'insert' and 'erase' operation of this data structure 
   has the complexity O(log n), it is iterable, the elements are iterated in 
   an key-ascending manner, and you can search for a key in O(log n) time.

5) For step in [0, 1, ..., 2*n]:
     If events[step].event is 'push':
       - Let i = events[step].corresponding_box_index
       - Insert a map boxes[i].x1 -> (i, 'left') to cross_section_map[]
       - Insert a map boxes[i].x2 -> (i, 'right') to cross_section_map[]
       - Search for a 'right'-typed key with x value no less than boxes[i].x2
       - Iterate from that key until you found a key, which corresponds to
         a box that contains boxes[i], or the x1 coordinate of which is larger
         than the x1 coordinate of a newly added box. In the first case, add
         boxes[i] to inner_boxes[].
     If events[step].event is 'pop':
       - Let i = events[step].corresponding_box_index
       - Erase the elements with the keys boxes[i].x1 and boxes[i].x2

现在,棘手的部分是该算法的步骤(4) 实现这样的数据结构似乎很困难。 但是,在 C++ 标准库中有一个开箱即用的精彩实现,称为std::map O(log n)中工作的搜索操作是std::map::lower_boundstd::map::upper_bound

该算法的平均复杂度为O(n log n) ,最坏情况复杂度为O(n^2) ,如果框的数量及其大小与图像大小相比相对较小,则复杂度接近O(n)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM