python 图像旋转与坐标旋转

1.图像旋转

image1=image1.rotate(angle)

np.rot90()

2.坐标旋转

 

一、首先来说一下关于像素旋转一定角度后的对应位置:

(1)旋转中心为左上角原点:

旋转有一个绕什么转的问题。我们先来看最简单的,绕第一个像素转,则旋转的情况会像这样:

令旋转前有

旋转a角度后有

以矩阵形式表示为

(2)旋转中心为图像中心:

当图片较大时,计算会很慢。主要是判断和计算太多了这里只讨论图像处理,程序的优化暂时放一边运行结果如下:

我们能看到,旋转后的图像有很多“蜂窝煤”。主要是点转换后要取整。导致原图中有些点映射到同一个点,而生成的图中有些点在原图中没有点映射到它。所以出现了很多“蜂窝煤”。果然理论还只是理论啊 下面我们来看看更通常一点的做法:以图像的中心为圆心进行旋转。这里涉及到一个坐标系的转换问题。看下图:

在矩阵中我们的坐标系通常是AB和AC方向的,而传统的笛卡尔直角坐标系是DE和DF方向的。令图像表示为M×N的矩阵,对于点A而言,两坐标系中的坐标分别是(0,0)和(-N/2,M/2)矩阵中点(x',y')转换为笛卡尔坐标系(x,y)的转换关系为:

逆变换为

于是我们得到图像以中心旋转的思路

  • 将矩阵坐标上点(原谅我这样称呼它)转换为笛卡尔坐标系
  • 将该点旋转a度。旋转公式前面已经给出了
  • 将旋转后的点再转换为矩阵坐标

于是得到最后结果

python中numpy有矩阵运算能力,但这里我们直接进行数值计算就可以了。用方程表示如下:

关键代码如下:

def rotatecordiate(angle,rect):
    angle=angle*math.pi/180
    n=1600
    m=1200
    def onepoint(x,y):
        # X = x*math.cos(angle) - y*math.sin(angle)-0.5*n*math.cos(angle)+0.5*m*math.sin(angle)+0.5*n
        # Y = y*math.cos(angle) + x*math.sin(angle)-0.5*n*math.sin(angle)-0.5*m*math.cos(angle)+0.5*m
        X = x * math.cos(angle) - y * math.sin(angle) - 0.5 * n * math.cos(angle) + 0.5 * m * math.sin(angle) + 0.5 * n
        Y = y * math.cos(angle) + x * math.sin(angle) - 0.5 * n * math.sin(angle) - 0.5 * m * math.cos(angle) + 0.5 * m
        return [int(X),int(Y)]
    newrect=[]
    for i in range(4):
        point=onepoint(rect[i*2],rect[i*2+1])
        newrect.extend(point)
    newrect.extend([1])
    print(newrect)
    return newrect

参考:https://www.cnblogs.com/zf-blog/p/8947800.html

(3)旋转中心为矩形框中心:

def rotatecordiate(angle,rect):
    anglePi = -angle * math.pi / 180.0
    cosA = math.cos(anglePi)
    sinA = math.sin(anglePi)

    x=rect[0]
    y=rect[1]
    width=rect[2]
    height=rect[3]
    x1 = x - 0.5 * width
    y1 = y - 0.5 * height

    x0 = x + 0.5 * width
    y0 = y1

    x2 = x1
    y2 = y + 0.5 * height

    x3 = x0
    y3 = y2

    x0n = (x0 - x) * cosA - (y0 - y) * sinA + x
    y0n = (x0 - x) * sinA + (y0 - y) * cosA + y

    x1n = (x1 - x) * cosA - (y1 - y) * sinA + x
    y1n = (x1 - x) * sinA + (y1 - y) * cosA + y

    x2n = (x2 - x) * cosA - (y2 - y) * sinA + x
    y2n = (x2 - x) * sinA + (y2 - y) * cosA + y

    x3n = (x3 - x) * cosA - (y3 - y) * sinA + x
    y3n = (x3 - x) * sinA + (y3 - y) * cosA + y

    return [(x0n,y0n),(x1n,y1n),(x2n,y2n),(x3n,y3n)]

绘制多边形:

plt.Polygon(rotatecordiate(angle,rect),color=color, fill=False, linewidth=2)

 

  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AICVer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值