Given a contour in OpenCV, I can extract the width and height by using cv2.boundingRect(contour)
. This returns the width and height of a bounding rectangle, as illustrated by the left figure.
Given an angle, is it possible to extract the width/height of a rotated bounding rectangle, as illustrated in the right figure?
I am trying to measure the length of moving objects, but I need to measure the length in the movement direction, which may sometimes be up to 45 degrees from the horizontal line.
I know there is a way of getting a rotated bounding rectangle, using cv2.minAreaRect
and cv2.boxPoints
, but the rotation I need will not always match the minimum area rectangle, so I need to be able to specify the angle somehow.
I only need the rotated width and height values, I don't really need the rotated contour, if that makes it easier.
As my comment: Why not. Support you have an angle, then you can make two orthogonality lines. Calculate the distance between pts and each line, then calc max_dist - min_dict, you will get width and height.
My mother language is Chinese
, and not I'm good at English writing. So I just turn it into code:
#!/usr/bin/python3
# 2017.12.13 22:50:16 CST
# 2017.12.14 00:13:41 CST
import numpy as np
def calcPointsWH(pts, theta=0):
# 计算离散点在特定角度的长宽
# Measuring width of points at given angle
th = theta * np.pi /180
e = np.array([[np.cos(th), np.sin(th)]]).T
es = np.array([
[np.cos(th), np.sin(th)],
[np.sin(th), np.cos(th)],
]).T
dists = np.dot(pts,es)
wh = dists.max(axis=0) - dists.min(axis=0)
print("==> theta: {}\n{}".format(theta, wh))
Give this diamond for testing:
pts = np.array([[100, 200],[200, 26],[300, 200],[200, 373]], np.int32)
for theta in range(0,91, 30):
calcPointsWH(pts, theta)
==> theta: 0
[ 200. 347.]
==> theta: 30
[ 173.60254038 300.51081511]
==> theta: 60
[ 300.51081511 173.60254038]
==> theta: 90
[ 347. 200.]
Now it's 2017.12.14 00:20:55 CST
, goodnight.