3.2 图像几何变换——旋转变换

理论

设原始图像的任意点 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0(x0,y0) 经顺时针旋转 β \beta β 角度后到新的位置 P ( x , y ) P(x,y) P(x,y),为表示方便,采用极坐标形式表示,原始点的角度为 α \alpha α。根据极坐标与直角坐标的关系,原始图像的点 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0(x0,y0) 的极坐标为

{ x 0 = r c o s α y 0 = r s i n α \left\{ \begin{matrix} x_0 = r {\rm cos} \alpha \\ y_0 = r {\rm sin} \alpha \end{matrix} \right. {x0=rcosαy0=rsinα

旋转到新位置以后 P ( x , y ) P(x, y) P(x,y) 的极坐标为

{ x = r c o s ( α − β ) = r c o s α c o s β + r s i n α s i n β y = r s i n ( α − β ) = r s i n α c o s β − r c o s α s i n β \left\{ \begin{matrix} x = r {\rm cos} (\alpha - \beta) = r{\rm cos}\alpha {\rm cos} \beta + r{\rm sin}\alpha {\rm sin}\beta\\ y = r {\rm sin} (\alpha - \beta) = r{\rm sin}\alpha {\rm cos} \beta - r{\rm cos}\alpha {\rm sin}\beta \end{matrix} \right. {x=rcos(αβ)=rcosαcosβ+rsinαsinβy=rsin(αβ)=rsinαcosβrcosαsinβ

由于旋转后的点 P ( x , y ) P(x, y) P(x,y) 需要用 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0(x0,y0) 表示,对上式进行简化,得

{ x = x 0 c o s β + y 0 s i n β y = − x 0 s i n β + y 0 c o s β \left\{ \begin{matrix} x = x_0 {\rm cos} \beta + y_0{\rm sin}\beta\\ y = -x_0 {\rm sin} \beta + y_0 {\rm cos}\beta \end{matrix} \right. {x=x0cosβ+y0sinβy=x0sinβ+y0cosβ

用矩阵表示如下:

[ x y 1 ] = [ c o s β s i n β 0 − s i n β c o s β 0 0 0 1 ] [ x 0 y 0 1 ] \left[\begin{matrix} x \\ y \\ 1 \end{matrix}\right]= \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & 0\\ -{\rm sin} \beta & {\rm cos} \beta & 0\\ 0 & 0 & 1 \end{matrix}\right] \left[\begin{matrix} x_0 \\ y_0 \\ 1 \end{matrix}\right] xy1=cosβsinβ0sinβcosβ0001x0y01

记上式中变换矩阵为

R = [ c o s β s i n β 0 − s i n β c o s β 0 0 0 1 ] R = \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & 0\\ -{\rm sin} \beta & {\rm cos} \beta & 0\\ 0 & 0 & 1 \end{matrix}\right] R=cosβsinβ0sinβcosβ0001
为旋转矩阵。

上述变换是针对原点的,如果指定了旋转中心,可以先按上述方式进行旋转,再把旋转后的中心平移到旋转前的中心。具体地,设旋转前的中线坐标为 C 0 ( x 0 , y 0 ) C_0(x_0, y_0) C0(x0,y0),则旋转后的坐标为 C ( x , y ) C(x,y) C(x,y),根据上面的关系,两个点的坐标关系即由上面矩阵变换确定。则旋转中心平移量为 C C 0 ⃗ = C 0 − C \vec{CC_0}=C_0 - C CC0 =C0C,代入 ( x , y ) (x,y) (x,y),可得
C C 0 ⃗ = [ Δ x Δ y ] = [ x 0 − x y 0 − y ] = [ x 0 ( 1 − c o s β ) − y 0 s i n β x 0 s i n β + y 0 ( 1 − s i n α ) ] \vec{CC_0}= \left[ \begin{matrix} \Delta x\\ \Delta y \end{matrix} \right]= \left[ \begin{matrix} x_0 - x\\ y_0 - y \end{matrix} \right]=\left[ \begin{matrix} x_0(1-{\rm cos} \beta) - y_0{\rm sin}\beta\\ x_0 {\rm sin} \beta + y_0 (1 - {\rm sin}\alpha) \end{matrix} \right] CC0 =[ΔxΔy]=[x0xy0y]=[x0(1cosβ)y0sinβx0sinβ+y0(1sinα)]

根据上一节,则平移对应的平移矩阵为

T = [ 1 0 Δ x 0 1 Δ y 0 0 1 ] T = \left[\begin{matrix} 1 & 0 & \Delta x\\ 0 & 1 & \Delta y\\ 0 & 0 & 1 \end{matrix}\right] T=100010ΔxΔy1

则旋转后再平移,对应矩阵为

M = T R = [ 1 0 Δ x 0 1 Δ y 0 0 1 ] [ c o s β s i n β 0 − s i n β c o s β 0 0 0 1 ] = [ c o s β s i n β Δ x − s i n β c o s β Δ y 0 0 1 ] = [ c o s β s i n β x 0 ( 1 − c o s β ) − y 0 s i n β − s i n β c o s β x 0 s i n β + y 0 ( 1 − s i n α ) 0 0 1 ] M = TR = \left[\begin{matrix} 1 & 0 & \Delta x\\ 0 & 1 & \Delta y\\ 0 & 0 & 1 \end{matrix}\right] \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & 0\\ -{\rm sin} \beta & {\rm cos} \beta & 0\\ 0 & 0 & 1 \end{matrix}\right] =\left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & \Delta x\\ -{\rm sin} \beta & {\rm cos}\beta &\Delta y\\ 0 & 0 & 1 \end{matrix}\right] =\left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & x_0(1-{\rm cos} \beta) - y_0{\rm sin}\beta \\ -{\rm sin} \beta & {\rm cos}\beta &x_0 {\rm sin} \beta + y_0 (1 - {\rm sin}\alpha)\\ 0 & 0 & 1 \end{matrix}\right] M=TR=100010ΔxΔy1cosβsinβ0sinβcosβ0001=cosβsinβ0sinβcosβ0ΔxΔy1=cosβsinβ0sinβcosβ0x0(1cosβ)y0sinβx0sinβ+y0(1sinα)1
对于 OPENCV 的

cv2.getRotationMatrix2D()

乘以缩放系数,并取了上述变换矩阵 M M M 的前两行(第三行恒为 [ 0 , 0 , 1 ] [0,0,1] [0,0,1]

实现

代码

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

def show(img):
    if img.ndim == 2:
        plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    else:
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        plt.imshow(img)
    plt.show()


img = cv.imread('pic/rabbit500x333.jpg')
# 以(80,100)为中心,顺时针旋转45度
rotateM = cv.getRotationMatrix2D((80, 100), 45, 1)
img_rotate = cv.warpAffine(img, rotateM, dsize=(500, 500))
show(img_rotate)

效果


说明:

  1. 未经许可,谢绝转载。
  2. 本教程为《数字图像处理Python OpenCV实战》的配套代码相关内容。
    免费视频教程为0-6章(标题号≤6),可在此处点击观看。
    所有课件及源代码可在此处下载:
    链接:https://pan.baidu.com/s/198PySe_vebO3e06idHSQ6g
    提取码:11o4
    有问题可在QQ群(1079300899)指出,进群答案:数字图像处理。在本文评论指出可能导致回复很晚。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值