1
votes

I have image, that is rotated by 30deg. However i need to rotate the bounding box too. The coordinations of bounding box are [xmin,ymin,xmax,ymax] = [101,27,270,388] (xmin,ymin) = top left corner , (xmax,ymax) = bottom right corner.

Now i wanted to rotate this matrix by running it over rotations matrix

theta = np.radians(30)
c, s = np.cos(theta), np.sin(theta)
r = np.array(((c,-s), (s, c)))

Using

labels = np.array([[101,270],[27,388]])
print(np.dot(r,labels))

But this trows incorrect values. If i am not mistaken the linear transformation should be correct did i overlook something or i made mistake somewhere? THanks for help.

enter image description here

1
Your matrix rotates points in the xy-plane counterclockwise through an angle θ about the origin of the Cartesian coordinate system. However, your origin is in the top left corner of the picture and not in its center and thus you're rotating about the wrong origin. - NewNewton
You are not rotating the box itself, just the min and max points around the origin. This just results in another axis aligned box with different dimensions. You must rotate all 4 points, and preferably around some center. - meowgoesthedog

1 Answers

0
votes

Option 1

you can simply use angle parameter in patches.Rectangle:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np
from skimage import data, io, filters

im = np.array(data.coins(), dtype=np.uint8)

# Create figure and axes
fig,ax = plt.subplots(1)

# Display the image
ax.imshow(im)

# Create a Rectangle patch
rect = patches.Rectangle((50,100),100,80,linewidth=1,edgecolor='r',facecolor='none')
rect_2 = patches.Rectangle((50,100),100,80,linewidth=1,edgecolor='r',facecolor='none', angle=30)

# Add the patch to the Axes
ax.add_patch(rect)
ax.add_patch(rect_2)

plt.show()

enter image description here

Option 2

Or if you want to do this in a mathematical way, use a rotation matrix. I just show you how can calculate the corner points of your rotated box

Previous corner points

enter image description here

First I set up the unrotated points:

x = [101,101,270, 270]
y = [27, 388, 27,388]

Now we create the rotation matrix

rot_mat = np.array([[np.cos(pi/6), -np.sin(pi/6)], [ np.sin(pi/6), np.cos(pi/6)]])

Now we centralize x and y, by shifting them (so that center of the rectangle is equivalent to the origin)

x_cen = np.array(x) - np.mean(x)
y_cen = np.array(y) -np.mean(y)

Apply the rotation matrix to the centralized arrays and shift back

x_rot = np.dot(rot_mat, np.array((x_cen,y_cen)))[0,:] + np.mean(x)
y_rot = np.dot(rot_mat, np.array((x_cen,y_cen)))[1,:] + np.mean(x)

Rotated corner points:

enter image description here