0

I want to merge these 2 rectangles into one, like this. The easiest way I can think to do this is getting the top y coordinate of the top rectangle and the bottom y coordinates of the bottom one and use them in cv2.rectangle(), but I am having trouble getting both these points because of a for loop.

Here is the code:

#Finding contours (always finds those 2 retangles + some noise):
_, conts, hierarchy = cv2.findContours(img_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for cnt in conts:
    area = cv2.contourArea(cnt)

    #filter all the noise
    if area > 20:

        x1, y1, w, h = cv2.boundingRect(cnt)
        x2 = x1 + w                           # (x1, y1) = top-left vertex
        y2 = y1 + h                           # (x2, y2) = bottom-right vertex
        cv2.rectangle(green_bar_win, (x1, y1), (x2, y2), (255,0,0), 2)
        print("x1:", x1, " y1:", y1, " x2:", x2, " y2:", y2)

Here is the print result (it prints the x,y coordinates of the top-left and bottom-right rectangle points for both rectangles in diferent itinerations of the loop):

x1: 60  y1: 217  x2: 83  y2: 288
x1: 60  y1: 169  x2: 83  y2: 216
x1: 60  y1: 217  x2: 83  y2: 288
x1: 60  y1: 169  x2: 83  y2: 216...

Thanks.

EDIT: my solution

Setti7
  • 149
  • 4
  • 16

2 Answers2

1

Instead of going with the coordinates, you can do it in a simpler way by using 'or'.

If both of the rectangles are of opencv type rect, you can simply use,

result = rect1 | rect2;

That will give you a rectangle enclosing both. Similarly, you can do other operations like

result = rect1 & rect2;

That'll give you the internsection of both the rectangles. Reference.

I.Newton
  • 1,753
  • 1
  • 10
  • 14
  • But how do I give different names for the rectangles? If i do what you are saying it would be `result = rect | rect` because `rect` is the only rectangle drawing that I have. As you can see in: `rect = cv2.rectangle(green_bar_win, (x1, y1), (x2, y2), (255,0,0), 2)` – Setti7 Feb 02 '18 at 16:00
  • I've used that in c++. If you want to try that, create a vector of rect and then pushback to it in the loop. Finally you can 'or' all the rect's. Otherwise, check this [LINK](http://answers.opencv.org/question/90455/how-to-perform-intersection-or-union-operations-on-a-rect-in-python/) for python. – I.Newton Feb 02 '18 at 18:53
0

There are many ways to achieve the result, some of it can be the following:

1) From the image, it is very clear that both the rectangles are very close to each other. So the contours must also be very close. Therefore before finding the contours, perform morphological transformations to the image. Mostly dilation will help. Find the working of this operation in the link.

dilation = cv2.dilate(img,kernel,iterations = 1)

2) Else if you only want to combine the rectangles, you can follow up with this link

Hope this helps!

janu777
  • 1,940
  • 11
  • 26
  • I am actually trying to find the big rectangle center point, and I have been thinking after posting my question, would it work if I calculated the center of the 2 smaller rectangles and average them? It would be a lot easier I suppose, because the x coordinates never changes, so I would be dealing only with two 'y' coordinates. – Setti7 Feb 02 '18 at 05:58
  • If you are very sure that only those two rectangles are going to be detected. You can very well merge them both. or find the center point of the large rectangle like that. – janu777 Feb 02 '18 at 06:01