I am writing an augmentation code to rotate annotated polygons inside images. I wrote a code but it’s not working right. Just Copy paste the code and you can get the results. Thank you for helping me out.
Image:
Need to rotate the image as well as a polygon for respective angle. Currently, I am not able to rotate the polygon
The image is rotated but the polygon is still in its place.
I tried This code. It rotates the polygon but not at the right position
import math from PIL import Image, ImageDraw from PIL import ImagePath from PIL import Image import matplotlib.pyplot as plt from math import sin, cos, radians import requests from io import BytesIO def rotatePolygon(polygon, degrees, height, width): """ Description: Rotate polygon the given angle about its center. Input: polygon (list of tuples) : list of tuples with (x,y) cordinates e.g [(1,2), (2,3), (4,5)] degrees int : Rotation Degrees Output: polygon (list of tuples) : Polygon rotated on angle(degrees) e.g [(1,2), (2,3), (4,5)] """ # Convert angle to radians theta = radians(degrees) # Getting sin and cos with respect to theta cosang, sinang = cos(theta), sin(theta) # find center point of Polygon to use as pivot y, x = [i for i in zip(*polygon)] # find center point of Polygon to use as pivot cx = width / 2 cy = height / 2 # Rotating every point new_points = [] for x, y in zip(x, y): tx, ty = x-cx, y-cy new_x = (tx*cosang + ty*sinang) + cx new_y = (-tx*sinang + ty*cosang) + cy new_points.append((new_y, new_x)) return new_points # Polygon xy = [(85, 384), (943, 374), (969, 474), (967, 527), (12, 540), (7, 490)] degrees = 270 # Getting Image from URL try: img = Image.open("polygon_image.png") except: url = "https://github.com/SohaibAnwaar/Mask---RCNN-Polygons-/blob/main/2_image_augmentation/extras/problamatic_image.jpg?raw=true" response = requests.get(url) img = Image.open(BytesIO(response.content)) img.save("polygon_image.png") # Rotating Image rotated_image = img.rotate(degrees,expand = True) h, w = img.size print("NotRotated", xy) rotated_xy = rotatePolygon(xy, 360 - (degrees), h, w) # Ploting Rotated Image img1 = ImageDraw.Draw(rotated_image) img1.polygon(rotated_xy, fill ="#FFF000", outline ="blue") # Ploting Straight Image img1 = ImageDraw.Draw(img) img1.polygon(xy, fill ="#FFF000", outline ="blue") plt.imshow(rotated_image) plt.show() plt.imshow(img) plt.show()
Advertisement
Answer
Rotation equations are:
xnew = x * cos(theta) - y * sin(theta) ynew = x * sin(theta) + y * cos(theta)
only mistake you are doing is this:
new_x = (tx*cosang - ty*sinang) + cy new_y = (tx*sinang + ty*cosang) + cx
After rotating image, cx and cy should be changed
Your complete code is as below:
import math import numpy as np from PIL import Image, ImageDraw from PIL import ImagePath from PIL import Image import matplotlib.pyplot as plt from math import sin, cos, radians import requests from io import BytesIO def rotatePolygon(polygon, degrees, height, width): """ Description: Rotate polygon the given angle about its center. Input: polygon (list of tuples) : list of tuples with (x,y) cordinates e.g [(1,2), (2,3), (4,5)] degrees int : Rotation Degrees Output: polygon (list of tuples) : Polygon rotated on angle(degrees) e.g [(1,2), (2,3), (4,5)] """ # Convert angle to radians theta = radians(degrees) # Getting sin and cos with respect to theta cosang, sinang = cos(theta), sin(theta) # find center point of Polygon to use as pivot y, x = [i for i in zip(*polygon)] # find center point of Polygon to use as pivot cx1 = width[0] / 2 cy1 = height[0] / 2 cx2 = width[1] / 2 cy2 = height[1] / 2 # Rotating every point new_points = [] for x, y in zip(x, y): tx, ty = x-cx1, y-cy1 new_x = (tx*cosang - ty*sinang) + cx2 new_y = (tx*sinang + ty*cosang) + cy2 new_points.append((new_y, new_x)) return new_points # Polygon xy = [(85, 384), (943, 374), (969, 474), (967, 527), (12, 540), (7, 490)] degrees = 270 # Getting Image from URL try: img = Image.open("polygon_image.png") except: url = "https://github.com/SohaibAnwaar/Mask---RCNN-Polygons-/blob/main/2_image_augmentation/extras/problamatic_image.jpg?raw=true" response = requests.get(url) img = Image.open(BytesIO(response.content)) img.save("polygon_image.png") # Rotating Image rotated_image = img.rotate(degrees,expand = True) h1, w1 = img.size h2, w2 = rotated_image.size print("NotRotated", xy) rotated_xy = rotatePolygon(xy, degrees, [h1,h2], [w1,w2]) # Ploting Rotated Image img1 = ImageDraw.Draw(rotated_image) img1.polygon(rotated_xy, fill ="#FFF000", outline ="blue") # Ploting Straight Image img1 = ImageDraw.Draw(img) img1.polygon(xy, fill ="#FFF000", outline ="blue") plt.imshow(rotated_image) plt.show() plt.imshow(img) plt.show()