简体   繁体   中英

How to combine overlapping rectangles in Python

I have various overlapping rectangles that are drawn on the image like this:

在此输入图像描述

I would like to consolidate these rectangles such that only the outer most rectangles are taken. For example, one rectangle for computer.org/webinars/Agile2 and one for FREE WEBINAR etc.

The way I'm drawing the rectangles is this:

import cv2
import numpy as np
.....
for rect in rects_new:
    #print (str(type(rect))) #<class 'numpy.ndarray'>
    #print (rect.area()) # gives error that 'numpy.ndarray' object has no attribute 'area'
    cv2.rectangle(vis, (rect[0],rect[1]), (rect[0]+rect[2],rect[1]+rect[3]), (0, 255, 255), 2)

I came across this answer https://stackoverflow.com/a/24061475/44286 and this answer http://answers.opencv.org/question/67091/how-to-find-if-2-rectangles-are-overlapping-each-other/?answer=67092#post-id-67092 that suggests opencv provides intersection of two rectangles with & . However, I'm not able to do this in python. When I call the area method I get an error (as shown in above snippet).

Question

How can I consolidate the rectangles such that when the rectangles are overlapping, then only the outer most rectangle is taken. I'd like to solve it in python by using the OpenCVs provided rectangle intersect & capability. As mentioned in this documentation http://docs.opencv.org/3.1.0/d2/d44/classcv_1_1Rect__.html#gsc.tab=0 and also mentioned in the linked answer posted above.

This could work:

def inOtherRect(rect_inner,rect_outer):
    return rect_inner[0]>=rect_outer[0] and \
        rect_inner[0]+rect_inner[2]<=rect_outer[0]+rect_outer[2] and \
        rect_inner[1]>=rect_outer[1] and \
        rect_inner[1]+rect_inner[3]<=rect_outer[1]+rect_outer[3] and \
        (rect_inner!=rect_outer)

outer_rects=[rects_new[:]]
for rect_inner in rects_new:
    for rect_outer in rects_new:
        if(inOtherRect(rect_inner,rect_outer)):
            if rect_inner in outer_rects:
                outer_rects.remove(rect_inner)


for rect in outer_rects:
    #print (str(type(rect))) #<class 'numpy.ndarray'>
    #print (rect.area()) # gives error that 'numpy.ndarray' object has no attribute 'area'
    cv2.rectangle(vis, (rect[0],rect[1]), (rect[0]+rect[2],rect[1]+rect[3]), (0, 255, 255), 2)

I iterate through all rectangles and remove the ones that are inside others from a copied list.

This is done extremely inefficent and ugly, but it should work (if I guessed your coordinate system right).

Note:

This only removes rectanlges that are inside another but not partially overlapping ones

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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