4

I have a set of regions (bounding boxes) for some image, example python code:

im = Image.open("single.png")
pix = np.array(im)
gray = rgb2grey(pix)
thresh = threshold_otsu(gray)
bw = closing(gray > thresh, square(1))

cleared = bw.copy()
clear_border(cleared)
borders = np.logical_xor(bw, cleared)
label_image = label(borders)

for region in regionprops(label_image, ['Area', 'BoundingBox']):
    #now i have bounding boxes in hand

What I would like to do is to merge regions which overlap or the distance between bbox edges is less than X. Naive approach would be checking distances between all regions, which has O(n2) complexity. I can write something smarter but I have impression that this kind of algorithm already exists and I don't want to reinvent the wheel. Any help is appreciated.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
mnowotka
  • 16,430
  • 18
  • 88
  • 134
  • How are you measuring the "distance" between bounding boxes? Do you mean "each edge in the bounding box is at most distance X" or "the total distance between the edges is X?" Also, how exactly do you want to merge them together? There are different ways that you can do this, but some might cause "cascade" effects where after merging two boxes, the new box then needs to get merged with a third. – templatetypedef Jan 04 '14 at 19:19
  • @templatetypedef Distance is defined as shortest distance between any two edges of two different boxes. Merging is creating bouding box around bounding boxes to be merged. – mnowotka Jan 04 '14 at 19:54
  • The problem of distance is a lot easier if you simply grow all the boxes by (distance/2). That at least reduces the problem to "do the boxes overlap". – kazagistar Jan 04 '14 at 21:26

1 Answers1

0

Is this your question "There is n boxes (not necessarily // to x-y axis), and you want to find all overlapping boxes and merge them if they exist?"

I cannot think of a linear algorithm yet but I have a rough idea faster than O(n^2), maybe O(n lg n) describes as follow:

  1. Give each box an id, also for each edge, mark it's belonging box
  2. Use sweeping line algorithm to find all intersections
  3. In the sweeping line algorithm, once an intersection is reported, you know which 2 boxes are overlapping, use something like disjoint-set to group them.
  4. Lastly linearly scan the disjoint-set, for each set, keep updating the leftmost, rightmost, topmost, bottommost point for making a larger box to bound them all (merging done here, note that if a box has no overlapping with others, the set will only contain itself)

I hope this method will work and it should be faster than O(n^2), but even if it does works, it still have some problems at step 4, where the larger merged box must be // to x-y axis, which is not a must.

Edit: Sorry I just go through OP again, and understand the above solution does not solve the "merge boxes with distance < x", it even only solves partly of the overlapping boxes problem.

Moreover, the merging box procedure is not a 1-pass job, it is kind of recursive, for example a box A and box B merged become box C, then box C may overlap / distance < x with box D..and so on.

To solve this task in linear time is quite impossible for me, as pre-computing the distance between all pair-wise box is already hardly be done in O(n)...

shole
  • 4,046
  • 2
  • 29
  • 69