opencv-24 图像几何变换03-仿射-cv2.warpAffine()

什么是仿射?

仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够

保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指 图像在完成仿射变换后,平行线仍然是平行线。

OpenCV 中的仿射函数为 cv2.warpAffine(),其通过一个变换矩阵(映射矩阵)M 实现变换,

具体为:

dst(𝑥, 𝑦) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)

如图 5-2 所示,可以通过一个变换矩阵 M,将原始图像 O 变换为仿射图像 R

因此,可以采用仿射函数 cv2.warpAffine()实现对图像的旋转,该函数的语法格式如下:

复制代码
dst = cv2.warpAffine( src, M, dsize[, flags[, borderMode[, borderValue]]] )

式中:

dst 代表仿射后的输出图像,该图像的类型和原始图像的类型相同。

dsize 决定输出图像的实际大小。

src 代表要仿射的原始图像。

M 代表一个 2×3 的变换矩阵。使用不同的变换矩阵,就可以实现不同的仿射变换。

dsize 代表输出图像的尺寸大小。

flags 代表插值方法,默认为 INTER_LINEAR。当该值为 WARP_INVERSE_MAP 时,

意味着 M 是逆变换类型,实现从目标图像 dst 到原始图像 src 的逆变换。

 borderMode 代表边类型, 默认为 BORDER_CONSTANT 。 当 该值为 BORDER_TRANSPARENT 时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常

值。

 borderValue 代表边界值,默认是 0。

通过以上分析可知,在 OpenCV 中使用函数 cv2.warpAffine()实现仿射变换,忽略其可选参数后的语法格式为:

复制代码
dst = cv2.warpAffine( src , M , dsize )

其通过转换矩阵 M 将原始图像 src 转换为目标图像 dst:

复制代码
dst(𝑥, 𝑦) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)

因此,进行何种形式的仿射变换完全取决于转换矩阵 M。下面分别介绍通过不同的转换矩阵 M 实现的不同的仿射变换。

平移

通过转换矩阵 M 实现将原始图像 src 转换为目标图像 dst:

dst(𝑥, 𝑦) = src(𝑀11𝑥 + 𝑀12𝑦 + 𝑀13, 𝑀21𝑥 + 𝑀22𝑦 + 𝑀23)

将原始图像 src 向右侧移动 100 个像素、向下方移动 200 个像素,则其对应关系为:

dst (x, y) = src (x + 100, y + 200)

将上述表达式补充完整,即:

dst (x, y) = src (1·x + 0·y + 100, 0·x + 1·y + 200)

根据上述表达式,可以确定对应的转换矩阵 M 中各个元素的值为:

 M11=1

 M12=0

 M13=100

 M21=0

 M22=1

 M23=200

将上述值代入转换矩阵 M,得到:

在已知转换矩阵 M 的情况下,可以直接利用转换矩阵 M 调用函数 cv2.warpAffine() 完成图像的平移。

实验:利用自定义转换矩阵完成图像平移。

复制代码
import cv2
import numpy as np
img=cv2.imread("lena.png")
height,width=img.shape[:2]
x=100
y=200
M = np.float32([[1, 0, x], [0, 1, y]])
move=cv2.warpAffine(img,M,(width,height))
cv2.imshow("original",img)
cv2.imshow("move",move)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

其中左图是原始图像,右图是移动结果图像

旋转

在使用函数 cv2.warpAffine()对图像进行旋转时,可以通过函数 cv2.getRotationMatrix2D()

获取转换矩阵。该函数的语法格式为:

复制代码
retval=cv2.getRotationMatrix2D(center, angle, scale)

式中:
 center 为旋转的中心点。
 angle 为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。
 scale 为变换尺度(缩放大小)。

利用函数 cv2.getRotationMatrix2D()可以直接生成要使用的转换矩阵 M。

例如,想要以图像中心为圆点,逆时针旋转 45°,并将目标图像缩小为原始图像的 0.6 倍,则在调用函数

cv2.getRotationMatrix2D()生成转换矩阵 M 时所使用的语句为:

复制代码
M=cv2.getRotationMatrix2D((height/2,width/2),45,0.6)

实验2:完成图像旋转

代码:

复制代码
import cv2
import numpy as np
img=cv2.imread("lena.png")
height,width=img.shape[:2]
M=cv2.getRotationMatrix2D((width/2,height/2),45,0.6)
rotate=cv2.warpAffine(img,M,(width,height))
cv2.imshow("original",img)
cv2.imshow("rotation",rotate)
cv2.waitKey()
cv2.destroyAllWindows()

其中左图是原始图像,右图是旋转结果图像

更复杂的仿射变换

对于更复杂仿射变换,OpenCV 提供了

函数 cv2.getAffineTransform()来生成仿射函数 cv2.warpAffine()所使用的转换矩阵 M。该函数的语法格式为:

复制代码
retval=cv2.getAffineTransform(src, dst)

式中:

 src 代表输入图像的三个点坐标。

 dst 代表输出图像的三个点坐标。

在该函数中,其参数值 src 和 dst 是包含三个二维数组(x, y)点的数组。上述参数通过函数

cv2.getAffineTransform()定义了两个平行四边形。src 和 dst 中的三个点分别对应平行四边形的

左上角、右上角、左下角三个点。函数 cv2.warpAffine()以函数 cv2.getAffineTransform()获取的

转换矩阵 M 为参数,将 src 中的点仿射到 dst 中。函数 cv2.getAffineTransform()

对所指定的点完成映射后,将所有其他点的映射关系按照指定点的关系计算确定。

实验3:完成图像仿射

复制代码
import cv2
import numpy as np
img=cv2.imread('lena.png')
rows,cols,ch=img.shape
#定义三个点
p1=np.float32([[0,0],[cols-1,0],[0,rows-1]])

print(p1)
#定义三个点的变换位置
p2=np.float32([[0,rows*0.33],[cols*0.85,rows*0.25],[cols*0.15,rows*0.7]])
print(p2)
#生成变换矩阵
M=cv2.getAffineTransform(p1,p2)
#进行仿射变换
dst=cv2.warpAffine(img,M,(cols,rows))
cv2.imshow("origianl",img)
cv2.imshow("result",dst)
cv2.waitKey()
cv2.destroyAllWindows()

首先构造了两个三分量的点集合 p1 和 p2,分别用来指代原始图像和目标图像内平行四边形的三个顶点(左上角、右上角、左下角)。

然后使用
M=cv2.getAffineTransform(p1,p2)

获取转换矩阵 M。接下来,
dst=cv2.warpAffine(img,M,(cols,rows))

完成了从原始图像到目标图像的仿射。

运行结果:

其中左图是原始图像,右图是仿射结果图像

相关推荐
用户51914958484530 分钟前
Braintree iOS Drop-in SDK - 一站式支付解决方案
人工智能·aigc
科技小郑32 分钟前
吱吱企业即时通讯以安全为基,重塑安全办公新体验
大数据·网络·人工智能·安全·信息与通信·吱吱企业通讯
就叫飞六吧35 分钟前
生产环境禁用AI框架工具回调:安全风险与最佳实践
人工智能·安全
胡乱编胡乱赢1 小时前
关于在pycharm终端连接服务器
人工智能·深度学习·pycharm·终端连接服务器
聚客AI1 小时前
⚠️Embedding选型指南:五步搞定数据规模、延迟与精度平衡!
人工智能·llm·掘金·日新计划
h_k100861 小时前
Manus AI与多语言手写识别
人工智能
就是一顿骚操作1 小时前
mcp解读——概述及整体架构
人工智能·大模型
程序猿阿伟1 小时前
《云原生边缘与AI训练场景:2类高频隐蔽Bug的深度排查与架构修复》
人工智能·云原生·bug
l1t1 小时前
利用美团龙猫添加xlsx的sheet.xml读取sharedStrings.xml中共享字符串输出到csv功能
xml·c语言·数据结构·人工智能·算法·解析器
IT_陈寒2 小时前
Python 3.12 的这5个新特性,让我的代码性能提升了40%!
前端·人工智能·后端