Skip to content
Advertisement

How to rotate a rectangle/bounding box together with an image

I’m working on a data augmentation and im trying to generate synthetic version of every image in my dataset. So i need to rotate images and together with bounding boxes as well in the images.

im only going to rotate images by 90, 180, 270 degrees.

I’m using pascal-voc annotation format as shown here. As a result i have following info.

x_min, y_min, x_max, y_max. Origin of image(i can get it from image size)

i’ve searched a lot on it. But i couldnt find any solution for rotating bounding boxes( or rectangles)

i’ve tried something like this; i’ve got this solution from here and tried to adapt it but didnt work.

def rotateRect(bndbox, img_size, angle):
    angle = angle * math.pi/180 # conversion from degree to radian
    y_min, y_max, x_min, x_max = bndbox
    ox, oy = img_size[0]/2, img_size[1]/2 # coordinate of origin of image
    rect = [[x_min, y_min], [x_min, y_max],[x_max, y_min],[x_max, y_max]] # coordinates of points of corners of bounding box rectangle.
    nrp = [[0, 0], [0,0 ],[0,0],[0, 0]] #new rectangle position

    for i, pt in enumerate(rect):
        newPx = int(ox + math.cos(angle) * (pt[0] - ox) - math.sin(angle) * (pt[1] - oy)) # new coordinate of point x
        newPy = int(oy + math.sin(angle) * (pt[0] - ox) + math.cos(angle) * (pt[1] - oy))  # new coordinate of point y
        nrp[i] = newPx,newPy
        nx_min, ny_min, nx_max, ny_max = nrp[0][0], nrp[0][1], nrp[2][0], nrp[2][1] # new bounding boxes values. 
     return [ny_min, ny_max, nx_min, nx_max]

thanks.

EDIT:

I need to get this rotation together with image and bounding box. First picture is original one, second one is rotated as 90 degree(counter-clockwise) and 3rd picture is rotated as -90 degree (counter-wise). i tried to rotate manually on paint to be precise. So i got these results.

   original of img size:(640x480)
   rotation orj, 90, -90
            --------------
    x_min = 98,  345, 17
    y_min = 345, 218, 98
    x_max = 420, 462, 420
    y_max = 462, 540, 134

Image Rotations; Original, 90 rotation, -90 rotation

Advertisement

Answer

i’ve found simpler way. enter image description here

Base on this aproach. We can do this calculation without using trigonometric calculations like this:

def rotate90Deg(bndbox, img_width): # just passing width of image is enough for 90 degree rotation.
   x_min,y_min,x_max,y_max = bndbox
   new_xmin = y_min
   new_ymin = img_width-x_max
   new_xmax = y_max
   new_ymax = img_width-x_min
   return [new_xmin, new_ymin,new_xmax,new_ymax]


rotate90Deg([98,345,420,462],640)

this can be used over and over again. And returns new bounding boxes values in Pascal-voc format.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement