簡體   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