如何在图像增强时同步旋转图像与标注多边形且无切边
修正方案
代码存在4处核心逻辑错误,修正后即可实现图像与多边形同步旋转对齐:
错误清单
- 宽高赋值颠倒:PIL的
Image.size返回值顺序为(宽度, 高度),原代码h, w = img.size将宽高赋值反了,导致旋转中心计算错误 - 坐标返回顺序颠倒:
rotatePolygon函数返回点时错误交换了x、y坐标,应为(new_x, new_y)而非(new_y, new_x) - 未适配expand后的坐标偏移:设置
expand=True后旋转后的图像尺寸会发生变化,需要给旋转后的多边形坐标增加对应偏移量才能匹配新图像坐标系 - 旋转角度匹配错误:PIL的
rotate方法默认是逆时针旋转,无需额外做360-degrees的角度转换
修正后完整代码
import math from PIL import Image, ImageDraw import matplotlib.pyplot as plt from math import sin, cos, radians import requests from io import BytesIO def rotatePolygon(polygon, degrees, orig_h, orig_w, new_h, new_w): """ 围绕原图像中心旋转多边形,并适配expand后新图像的坐标偏移 输入: polygon (list of tuples) : 多边形坐标列表,格式为[(x1,y1), (x2,y2)...] degrees int : 旋转角度(逆时针) orig_h int : 原图像高度 orig_w int : 原图像宽度 new_h int : 旋转后图像高度 new_w int : 旋转后图像宽度 输出: polygon (list of tuples) : 旋转后的多边形坐标 """ theta = radians(degrees) cosang, sinang = cos(theta), sin(theta) # 原图像旋转中心 cx = orig_w / 2 cy = orig_h / 2 new_points = [] for x, y in polygon: tx, ty = x - cx, y - cy # 逆时针旋转坐标变换 new_x = tx * cosang - ty * sinang + cx new_y = tx * sinang + ty * cosang + cy # 适配expand后的新图像坐标偏移 offset_x = (new_w - orig_w) / 2 offset_y = (new_h - orig_h) / 2 new_x += offset_x new_y += offset_y new_points.append((new_x, new_y)) return new_points # 配置参数 xy = [(85, 384), (943, 374), (969, 474), (967, 527), (12, 540), (7, 490)] degrees = 270 # 读取图像 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") # 正确获取原图像宽高 orig_w, orig_h = img.size # 旋转图像 rotated_image = img.rotate(degrees, expand=True) # 获取旋转后图像宽高 new_w, new_h = rotated_image.size # 旋转多边形 rotated_xy = rotatePolygon(xy, degrees, orig_h, orig_w, new_h, new_w) # 绘制旋转后的结果 img1 = ImageDraw.Draw(rotated_image) img1.polygon(rotated_xy, fill ="#FFF000", outline ="blue") # 绘制原图结果 img2 = ImageDraw.Draw(img) img2.polygon(xy, fill ="#FFF000", outline ="blue") # 显示结果 plt.imshow(rotated_image) plt.show() plt.imshow(img) plt.show()
内容的提问来源于stack exchange,提问作者Sohaib Anwaar
相关产品推荐
相关产品推荐

