Skip to content

Instantly share code, notes, and snippets.

@alxcnwy
Created June 23, 2021 14:44
Show Gist options
  • Save alxcnwy/358907f8af0d9c51620f3227b6f81c77 to your computer and use it in GitHub Desktop.
Save alxcnwy/358907f8af0d9c51620f3227b6f81c77 to your computer and use it in GitHub Desktop.
Rotate bounding box and get new bounding coords
# answer to this reddit post:
# https://www.reddit.com/r/learnmachinelearning/comments/o6br1e/calculate_bounding_box_coordinates_from_contour/
import numpy as np
from numpy import sin, cos, sqrt, pi
import math
import matplotlib.pyplot as plt
center = (332, 209)
width = 56
height = 33
degrees = -77
# topleft
pt1 = [center[0] - width, center[1] - height]
# btmleft
pt2 = [center[0] - width, center[1] + height]
# btmright
pt3 = [center[0] + width, center[1] + height]
# topright
pt4 = [center[0] + width, center[1] - height]
def rotate(origin, point, angle):
"""
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
modified from answer here: https://stackoverflow.com/questions/34372480/rotate-point-about-another-point-in-degrees-python
"""
ox, oy = origin
px, py = point
qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
return int(qx), int(qy)
rectangle = [pt1, pt2, pt3, pt4, pt1]
rectangle_rotated = [rotate(center, pt, math.radians(degrees)) for pt in rectangle]
rectangle = np.array(rectangle)
rectangle_rotated = np.array(rectangle_rotated)
# these are what you need
x_min, y_min = np.min(rectangle_rotated,axis=0)
x_max, y_max = np.max(rectangle_rotated,axis=0)
# create bounding rect points
pt1 = [x_min, y_min]
pt2 = [x_min, y_max]
pt3 = [x_max, y_max]
pt4 = [x_max, y_min ]
rectangle_bounding = [pt1, pt2, pt3, pt4, pt1]
# plot input rectangle in blue, rotated in red, bounding in green
plt.plot(np.array(rectangle)[:,0], np.array(rectangle)[:,1], "bo-")
plt.plot(np.array(rectangle_rotated)[:,0], np.array(rectangle_rotated)[:,1], "ro-")
plt.plot(np.array(rectangle_bounding)[:,0], np.array(rectangle_bounding)[:,1], "go-")
plt.show()
print(f"Rotated bounding rectangle: ({x_min},{y_min}), ({x_max},{y_max})")
@bhavyashah2409
Copy link

The calculation of top left, top right, bottom left and bottom right coordinates are wrong. They should be as follows for a rectangular bounding box:
xmin = x_centre - (bbox_w / 2)
ymin = y_centre - (bbox_h / 2)
xmax = x_centre + (bbox_w / 2)
ymax = y_centre + (bbox_h / 2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment