一个需求是,将在一张图片中识别出来的一个不规则图像,得到其四个端点的坐标,要以其顶边为水平线,将其摆正.示例如下:
![](https://img.haomeiwen.com/i8777535/c41e81b0c72b0c97.jpg)
在得知原图中四个端点(红色的点)的情况下,可得到上述结果图.
- 源代码:
import math
from PIL import Image, ImageDraw
class Rotate(object):
def __init__(self, image: Image.Image, coordinate):
self.image = image.convert('RGB')
self.coordinate = coordinate
self.xy = [tuple(self.coordinate[k]) for k in ['left_top', 'right_top', 'right_bottom', 'left_bottom']]
self._mask = None
self.image.putalpha(self.mask)
@property
def mask(self):
if not self._mask:
mask = Image.new('L', self.image.size, 0)
draw = ImageDraw.Draw(mask, 'L')
draw.polygon(self.xy, fill=255)
self._mask = mask
return self._mask
def run(self):
image = self.rotation_angle()
box = image.getbbox()
return image.crop(box)
def rotation_angle(self):
x1, y1 = self.xy[0]
x2, y2 = self.xy[1]
angle = self.angle([x1, y1, x2, y2], [0, 0, 10, 0]) * -1
return self.image.rotate(angle, expand=True)
def angle(self, v1, v2):
dx1 = v1[2] - v1[0]
dy1 = v1[3] - v1[1]
dx2 = v2[2] - v2[0]
dy2 = v2[3] - v2[1]
angle1 = math.atan2(dy1, dx1)
angle1 = int(angle1 * 180 / math.pi)
angle2 = math.atan2(dy2, dx2)
angle2 = int(angle2 * 180 / math.pi)
if angle1 * angle2 >= 0:
included_angle = abs(angle1 - angle2)
else:
included_angle = abs(angle1) + abs(angle2)
if included_angle > 180:
included_angle = 360 - included_angle
return included_angle
if __name__ == '__main__':
image = Image.open('src/2.jpg')
coordinate = {'left_top': [51, 305], 'right_top': [486, 67], 'right_bottom': [647, 326], 'left_bottom': [213, 584]}
rotate = Rotate(image, coordinate)
rotate.run().show()
网友评论