旋转多边形而不剪切边

2024-05-16 11:19:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个增强代码来旋转图像中带注释的多边形。我写了一个代码,但它不能正常工作。只要复制粘贴代码,就可以得到结果。谢谢你帮助我

图像:

enter image description here

需要旋转图像以及相应角度的多边形。目前,我无法旋转多边形

enter image description here

图像已旋转,但多边形仍在其位置

我试过这个密码。它旋转多边形,但不在正确的位置

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()

Tags: offrom图像imageimportimgnewplt
2条回答

旋转方程为:

xnew = x * cos(theta) - y * sin(theta)
ynew = x * sin(theta) + y * cos(theta)

您所犯的唯一错误是:

new_x = (tx*cosang - ty*sinang) + cy
new_y = (tx*sinang + ty*cosang) + cx

旋转图像后,应更改cx和cy

您的完整代码如下所示:

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()

对于向右旋转直角,使用以下等式(假设X/U从左到右和Y/V自上而下):

U = H - Y
V = X

其中图像大小为W x H

相关问题 更多 >