# Opencv separate overlapping rectangles

**URL:** <https://forum.opencv.org/t/opencv-separate-overlapping-rectangles/15751>\
**Category:** Python\
**Created:** [December 6, 2023, 7:11am UTC](https://forum.opencv.org/t/opencv-separate-overlapping-rectangles/15751 "2023-12-06T07:11:33Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![MobileRobotics](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/mobilerobotics/32/8060_2.png) [@MobileRobotics](https://forum.opencv.org/u/MobileRobotics)\
**Post date:** [December 6, 2023, 7:11am UTC](https://forum.opencv.org/t/opencv-separate-overlapping-rectangles/15751/1 "2023-12-06T07:11:33Z")

</div>

![](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/7/77b293756886ddb28e4158e68590a550722bdeba.png)  
This image is the first processed image from a map created with a LiDAR sensor.  
If you look closely at the image, there are many bumpy parts that are not exactly straight lines.

 ![](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/7/74ebfdd187d643ffc19c81ea62b969d6bc4bf831.png)  
I want to make the result like this image.

 ![](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/2/247faf5bd5ce95a6613461ab85de75141723123e.png)  
This is the first map image scanned with LiDAR.

I tried using the hough line, but it’s not perfect.  
I would like to figure out a method that can be applied in different situations

Here is my code.

```auto
import numpy as np
import math
import cv2

def get_dist(pt1, pt2):
    return math.hypot(pt1[0]-pt2[0], pt1[1]-pt2[1])
def reorderPts(pts):
    idx = np.lexsort((pts[:, 1], pts[:, 0]))
    pts = pts[idx]

    if pts[0, 1] > pts[1, 1]:
        pts[[0, 1]] = pts[[1, 0]]

    if pts[2, 1] < pts[3, 1]:
        pts[[2, 3]] = pts[[3, 2]]

    return pts

def solve(src):
    H, W = src.shape[:2]
    dst = src.copy()

    gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    _, bin = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    bin = cv2.erode(bin, np.ones((5, 5)))

    cv2.floodFill(bin, np.zeros((H+2, W+2), np.uint8), (0, 0), 0)
    bin = cv2.medianBlur(bin, 7)

    nonRectArea = bin.copy()
    cv2.floodFill(nonRectArea, np.zeros((H+2, W+2), np.uint8), (W//2, H//2), 0)
    bin[np.where(nonRectArea == 255)] = 0

    contours, _ = cv2.findContours(bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    rect = cv2.minAreaRect(contours[0])
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    cv2.drawContours(dst, [box], 0, (0, 255, 0), 1)

    srcQuad = reorderPts(box.reshape(4, 2).astype(np.float32))
    dw = int(get_dist(srcQuad[0], srcQuad[3])*2)
    dh = int(get_dist(srcQuad[0], srcQuad[1])*2)
    dstQuad = np.array([[0, 0], [0, dh], [dw, dh], [dw, 0]], np.float32)
    pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
    dst = cv2.warpPerspective(src, pers, (dw, dh))

    gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((25, 25)))

    lines = cv2.HoughLinesP(thresh, 0.8, np.pi/180, 80, minLineLength=30, maxLineGap=100)
    w, h = dst.shape[:2]
    mask = np.zeros((w, h), dtype=np.uint8)
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(dst, (x1,y1), (x2, y2), (0,255,0), 3)
        cv2.line(mask, (x1,y1), (x2, y2), 255, 3)

    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((7, 7), dtype=np.uint8))
    thresh = cv2.bitwise_and(thresh,thresh,mask=~mask)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, np.ones((9, 9), dtype=np.uint8))

    cv2.imshow("src", src)
    cv2.imshow("dst", dst)
    cv2.imshow("thresh", thresh)
    cv2.waitKey()

src = cv2.imread('map.png')
solve(src)

```

This is code result.

 ![](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/2/24932978819fed68d9a3b72de19880eb80c5f3fe.png)  
 ![](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/7/7f8242007edb3b2481285583578e91c44ad62b4e.png)
