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
JavaScript
x
93
93
1
import math
2
from PIL import Image, ImageDraw
3
from PIL import ImagePath
4
from PIL import Image
5
import matplotlib.pyplot as plt
6
from math import sin, cos, radians
7
import requests
8
from io import BytesIO
9
10
def rotatePolygon(polygon, degrees, height, width):
11
"""
12
Description:
13
14
Rotate polygon the given angle about its center.
15
16
Input:
17
polygon (list of tuples) : list of tuples with (x,y) cordinates
18
e.g [(1,2), (2,3), (4,5)]
19
20
degrees int : Rotation Degrees
21
22
Output:
23
24
polygon (list of tuples) : Polygon rotated on angle(degrees)
25
e.g [(1,2), (2,3), (4,5)]
26
27
"""
28
# Convert angle to radians
29
theta = radians(degrees)
30
31
# Getting sin and cos with respect to theta
32
cosang, sinang = cos(theta), sin(theta)
33
34
# find center point of Polygon to use as pivot
35
y, x = [i for i in zip(*polygon)]
36
37
# find center point of Polygon to use as pivot
38
39
cx = width / 2
40
cy = height / 2
41
42
# Rotating every point
43
new_points = []
44
for x, y in zip(x, y):
45
tx, ty = x-cx, y-cy
46
new_x = (tx*cosang + ty*sinang) + cx
47
new_y = (-tx*sinang + ty*cosang) + cy
48
new_points.append((new_y, new_x))
49
return new_points
50
51
52
53
# Polygon
54
xy = [(85, 384), (943, 374), (969, 474), (967, 527), (12, 540), (7, 490)]
55
degrees = 270
56
57
58
# Getting Image from URL
59
try:
60
img = Image.open("polygon_image.png")
61
except:
62
url = "https://github.com/SohaibAnwaar/Mask---RCNN-Polygons-/blob/main/2_image_augmentation/extras/problamatic_image.jpg?raw=true"
63
response = requests.get(url)
64
img = Image.open(BytesIO(response.content))
65
img.save("polygon_image.png")
66
67
68
69
# Rotating Image
70
rotated_image = img.rotate(degrees,expand = True)
71
h, w = img.size
72
73
print("NotRotated", xy)
74
rotated_xy = rotatePolygon(xy, 360 - (degrees), h, w)
75
76
77
78
# Ploting Rotated Image
79
img1 = ImageDraw.Draw(rotated_image)
80
img1.polygon(rotated_xy, fill ="#FFF000", outline ="blue")
81
82
83
# Ploting Straight Image
84
img1 = ImageDraw.Draw(img)
85
img1.polygon(xy, fill ="#FFF000", outline ="blue")
86
87
plt.imshow(rotated_image)
88
plt.show()
89
90
91
plt.imshow(img)
92
plt.show()
93
Advertisement
Answer
Rotation equations are:
JavaScript
1
3
1
xnew = x * cos(theta) - y * sin(theta)
2
ynew = x * sin(theta) + y * cos(theta)
3
only mistake you are doing is this:
JavaScript
1
3
1
new_x = (tx*cosang - ty*sinang) + cy
2
new_y = (tx*sinang + ty*cosang) + cx
3
After rotating image, cx and cy should be changed
Your complete code is as below:
JavaScript
1
97
97
1
import math
2
import numpy as np
3
from PIL import Image, ImageDraw
4
from PIL import ImagePath
5
from PIL import Image
6
import matplotlib.pyplot as plt
7
from math import sin, cos, radians
8
import requests
9
from io import BytesIO
10
11
def rotatePolygon(polygon, degrees, height, width):
12
"""
13
Description:
14
15
Rotate polygon the given angle about its center.
16
17
Input:
18
polygon (list of tuples) : list of tuples with (x,y) cordinates
19
e.g [(1,2), (2,3), (4,5)]
20
21
degrees int : Rotation Degrees
22
23
Output:
24
25
polygon (list of tuples) : Polygon rotated on angle(degrees)
26
e.g [(1,2), (2,3), (4,5)]
27
28
"""
29
# Convert angle to radians
30
theta = radians(degrees)
31
32
# Getting sin and cos with respect to theta
33
cosang, sinang = cos(theta), sin(theta)
34
35
# find center point of Polygon to use as pivot
36
y, x = [i for i in zip(*polygon)]
37
38
# find center point of Polygon to use as pivot
39
40
cx1 = width[0] / 2
41
cy1 = height[0] / 2
42
cx2 = width[1] / 2
43
cy2 = height[1] / 2
44
45
# Rotating every point
46
new_points = []
47
for x, y in zip(x, y):
48
tx, ty = x-cx1, y-cy1
49
new_x = (tx*cosang - ty*sinang) + cx2
50
new_y = (tx*sinang + ty*cosang) + cy2
51
new_points.append((new_y, new_x))
52
return new_points
53
54
55
56
# Polygon
57
xy = [(85, 384), (943, 374), (969, 474), (967, 527), (12, 540), (7, 490)]
58
degrees = 270
59
60
61
# Getting Image from URL
62
try:
63
img = Image.open("polygon_image.png")
64
except:
65
url = "https://github.com/SohaibAnwaar/Mask---RCNN-Polygons-/blob/main/2_image_augmentation/extras/problamatic_image.jpg?raw=true"
66
response = requests.get(url)
67
img = Image.open(BytesIO(response.content))
68
img.save("polygon_image.png")
69
70
71
72
# Rotating Image
73
rotated_image = img.rotate(degrees,expand = True)
74
h1, w1 = img.size
75
h2, w2 = rotated_image.size
76
77
print("NotRotated", xy)
78
rotated_xy = rotatePolygon(xy, degrees, [h1,h2], [w1,w2])
79
80
81
82
# Ploting Rotated Image
83
img1 = ImageDraw.Draw(rotated_image)
84
img1.polygon(rotated_xy, fill ="#FFF000", outline ="blue")
85
86
87
# Ploting Straight Image
88
img1 = ImageDraw.Draw(img)
89
img1.polygon(xy, fill ="#FFF000", outline ="blue")
90
91
plt.imshow(rotated_image)
92
plt.show()
93
94
95
plt.imshow(img)
96
plt.show()
97