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:
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()
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: