Home > Enterprise >  How to "stretch" out a bounding box given from minAreaRect function in openCV?
How to "stretch" out a bounding box given from minAreaRect function in openCV?

Time:12-01

I wish to run a line detector between two known points on an image but firstly I need to widen the area around the line so my line detector has more area to work with. The main issue it stretch the area around line with respect to the line slope. For instance: enter image description here


We may also want to expand the box in the parallel direction.
I am still not sure about the signs...

In this case it's simpler to update input_to_min_area:

import cv2
import numpy as np

img = cv2.imread('sketch.png')

#input_to_min_area = np.array([[584, 147], [587, 502]]) # this works instead of contour as an input to minAreaRect
#input_to_min_area = np.array([[109, 515], [585, 144]]) # this works instead of contour as an input to minAreaRect
input_to_min_area = np.array([[80, 103], [590, 502]]) # this works instead of contour as an input to minAreaRect

rect = cv2.minAreaRect(input_to_min_area)

angle = np.deg2rad(rect[2])  # Angle of minAreaRect
pad_x = int(round(20*np.cos(angle)))
pad_y = int(round(20*np.sin(angle)))
tmp_to_min_area = np.array([[input_to_min_area[0, 0] pad_x, input_to_min_area[0, 1] pad_y], [input_to_min_area[1, 0]-pad_x, input_to_min_area[1, 1]-pad_y]])
rect = cv2.minAreaRect(tmp_to_min_area)

box = cv2.boxPoints(rect)

angle = np.deg2rad(rect[2])  # Angle of minAreaRect

# Padding in each direction is perpendicular to the angle of minAreaRect
pad_x = 20*np.sin(angle)
pad_y = 20*np.cos(angle)

box[[0, 3], 0] -= pad_x
box[[1, 2], 0]  = pad_x
box[[0, 3], 1]  = pad_y
box[[1, 2], 1] -= pad_y

box = np.int0(box)

cv2.drawContours(img, [box], 0, (0, 255, 255), 2)

cv2.line(img, (tmp_to_min_area[0, 0], tmp_to_min_area[0, 1]), (tmp_to_min_area[1, 0], tmp_to_min_area[1, 1]), (255, 0, 0), 2)

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

Output:
enter image description here

CodePudding user response:

A minAreaRect() gives you a center point, the size of the rectangle, and an angle.

You could just add to the shorter side length of the rectangle. Then you have a description of a "wider rectangle". You can then do with it whatever you want, such as call boxPoints() on it.

padding = 42

rect = cv.minAreaRect(input_to_min_area)

(center, (w,h), angle) = rect # take it apart

if w < h: # we don't know which side is longer, add to shorter side
    w  = padding
else:
    h  = padding

rect = (center, (w,h), angle) # rebuild

A box around your two endpoints, widened:

enter image description here

  • Related