基于 OpenCV 的图像几何变换:缩放、翻转、旋转、仿射与透视变换的原理、实现及应用
本文介绍了四种常见的图像几何变换操作:缩放、翻转、旋转和仿射变换。图像缩放(resize)通过调整像素尺寸实现,需注意比例以避免变形;翻转(flip)可实现上下、左右或双向镜像效果;旋转(rotate)支持90度倍数的固定角度旋转;仿射变换(warpAffine)则能实现平移、任意角度旋转及更复杂的几何变换。每种操作均通过OpenCV实现,并附代码示例和效果对比图,展示了参数调整对结果的影响,如变
一,图像的放大和缩小
## 图像缩放的本质
图像缩放是通过改变图像的像素尺寸(宽度和高度)来调整图像大小的操作,本质是对原图像的像素进行重新采样(放大时补充像素,缩小时减少像素)。
import numpy as np
import cv2
#图像缩放,可能会导致图像变形,是因为缩放比列不对
lh = cv2.imread('10.jpg')
#dsize(x,y)宽高
new = cv2.resize(lh,(240,314))
#new = cv2.resize(lh,None,fx=0.3,fy=0.3)#取宽高的1/3
#按比例缩放,所以要先知道宽高,输出是高宽
print(lh.shape)
cv2.imshow('left',lh)
cv2.imshow('right',new)
cv2.waitKey(0)
输出结果如下:
代码解释
new = cv2.resize(lh, (240, 314)) # (宽, 高)
直接指定缩放后的目标宽度(240)和高度(314)
若目标尺寸的宽高比例与原图不一致,会导致图像变形(例如原图是正方形,缩放到长方形时会拉伸或挤压)
new = cv2.resize(lh, None, fx=0.3, fy=0.3) # 宽高均缩放到原图的30%
fx:宽度缩放比例(>1 为放大,<1 为缩小)
fy:高度缩放比例
当fx=fy时,图像按原比例缩放,不会变形。
放大与缩小的区别
图像缩小:需要从原图像中筛选保留部分像素(通常通过均值、插值等方式),可能导致细节丢失,但图像文件体积会减小。
图像放大:需要通过算法补充新的像素(如双线性插值、最近邻插值等),可能导致图像模糊(像素拉伸),文件体积会增大。
注意点
OpenCV 中图像的shape输出为(高, 宽, 通道数),而resize的dsize参数是(宽, 高),使用时需注意尺寸对应关系。
按比例缩放时,先通过lh.shape获取原图宽高(宽=lh.shape[1],高=lh.shape[0]),再计算目标尺寸可避免变形。
二,图像的翻转
图像翻转是一种常见的几何变换,主要通过改变像素的排列顺序实现,与旋转(按角度转动)的效果不同,翻转更像是 “镜像” 或 “倒置” 处理。
#图像翻转,与旋转不同,旋转是按照角度旋转
import numpy as np
import cv2
lh = cv2.imread('10.jpg')
#上下翻转
new = cv2.flip(lh, 0)
#左右翻转
new2 = cv2.flip(lh, 1)
#上下加左右翻转
new3 = cv2.flip(lh, -1)
cv2.imshow('original', lh)
cv2.imshow('flipped', new)
cv2.imshow('flipped2', new2)
cv2.imshow('flipped3', new3)
cv2.waitKey(0)
输出结果对比:
代码解释
核心函数:cv2.flip()
函数作用:对图像进行水平、垂直或同时水平垂直翻转,
new = cv2.flip(lh, 0) # flipCode=0
src:输入的原始图像
flipCode:翻转模式参数,决定翻转方向
1)垂直翻转(上下翻转)
new = cv2.flip(lh, 0) # flipCode=0
效果:图像上下颠倒,如同将图像沿水平中线(横向中线)翻转,顶部像素移到底部,底部像素移到顶部。
例:照片中的人物会变成 “头朝下、脚朝上”。
2)水平翻转(左右翻转)
new2 = cv2.flip(lh, 1) # flipCode=1
效果:图像左右颠倒,如同沿垂直中线(纵向中线)翻转,左侧像素移到右侧,右侧像素移到左侧。
例:类似照镜子的效果,文字会变成反方向(如 “ABC” 变成 “CBA”)。
3)水平 + 垂直翻转(上下 + 左右同时翻转)
new3 = cv2.flip(lh, -1) # flipCode=-1
效果:先上下翻转,再左右翻转(或先左右再上下,结果一致),相当于图像旋转 180 度的效果,但实现方式不同(翻转是像素镜像,旋转是角度变换)。
例:人物既头朝下,又左右颠倒。
翻转的特点
无变形:翻转不会改变图像的尺寸和像素值,仅改变像素的位置顺序,图像内容的比例和形状保持不变。
实时性:操作简单,计算效率高,适合快速处理图像。
应用场景:常用于数据增强(如训练神经网络时扩充样本)、镜像效果制作、纠正图像方向(如照片拍反时调整)等。
通过调整flipCode参数,cv2.flip()可以灵活实现不同方向的翻转,是图像处理中常用的基础操作。
三,图像的旋转
图像旋转的核心概念
图像旋转是将图像围绕某个某一中心点(通常是图像中心)按指定角度转动的几何变换,会改变像素的空间位置,但不改变像素本身的颜色值。代码中演示的是固定角度旋转(90 度、180 度、270 度),这类旋转属于特殊情况,操作简单且不会产生图像裁剪或黑边(除非尺寸变化)。
使用 OpenCV 的cv2.rotate()函数实现图像旋转的操作,主要针对 90 度倍数的固定角度旋转。
#图像旋转,顺时针,不能转小角度(不是90度的倍数)
import numpy as np
import cv2
lh =cv2.imread('10.jpg')
#旋转90度
new = cv2.rotate(lh, cv2.ROTATE_90_CLOCKWISE)
#旋转180度
new2 = cv2.rotate(lh,cv2.ROTATE_180)
#旋转270度
new3 = cv2.rotate(lh, cv2.ROTATE_90_COUNTERCLOCKWISE)
cv2.imshow('original', lh)
cv2.imshow('rotated', new)
cv2.imshow('rotated2', new2)
cv2.imshow('rotated3', new3)
cv2.waitKey(0)
输出结果:


代码解释
核心函数:cv2.rotate()
函数作用:实现图像按 90 度倍数的顺时针或逆时针旋转。
cv2.rotate(src, rotateCode)
src:输入的原始图像
rotateCode:旋转模式参数,指定旋转角度和方向
1)顺时针旋转 90 度
new = cv2.rotate(lh, cv2.ROTATE_90_CLOCKWISE)
效果:图像顺时针转动 90 度,旋转后图像的宽高会互换(原图宽 × 高 → 新图高 × 宽)。
例:一张宽 600、高 400 的图像,旋转后变为宽 400、高 600。
2)旋转 180 度
new2 = cv2.rotate(lh, cv2.ROTATE_180)
效果:图像顺时针(或逆时针)旋转 180 度,宽高不变,但像素位置完全颠倒(相当于上下 + 左右翻转的组合效果,但本质是旋转)。
3)逆时针旋转 90 度(或顺时针旋转 270 度)
new3 = cv2.rotate(lh, cv2.ROTATE_90_COUNTERCLOCKWISE)
效果:图像逆时针转动 90 度,宽高同样互换(与顺时针 90 度旋转方向相反)。
固定角度旋转的特点
无裁剪 / 黑边:由于旋转角度是 90 度的倍数,旋转后图像刚好填满新尺寸,不会出现像素丢失或黑边(与任意角度旋转不同)。
尺寸变化:90 度和 270 度旋转会交换图像的宽和高;180 度旋转尺寸不变。
高效性:操作简单,计算速度快,适合快速调整图像方向(如纠正拍倒的照片)。
补充:任意角度旋转
如果需要旋转非 90 度倍数的角度(如 30 度、45 度),cv2.rotate()无法直接实现,需通过旋转矩阵和cv2.warpAffine()函数,下面内容展示。
四,仿射变换
仿射变换是一种保持图像 “平行性” 和 “共线比例” 的几何变换,能实现平移、旋转、缩放、剪切等多种效果。
仿射变换的核心特点
保持平行性:变换后,原图像中的平行线依然平行。
保持共线比例:原图像中共线的点,变换后仍共线,且点之间的比例关系不变。
通过矩阵实现:所有仿射变换都可以通过一个 2×3 的变换矩阵(M)描述,
仿射变换类型及实现
OpenCV 中通过cv2.warpAffine()函数应用仿射变换。
#代码稍微有点乱,只保留一个M,不同场景
import numpy as np
import cv2
lh = cv2.imread('10.jpg')
h,w,ch = lh.shape
#变换矩阵,np.float32,参数,200横向平移(左右),300纵向平移(上下)
#M = np.float32([[1,0,200],[0,1,300]])
#旋转的角度为逆时针 ,1.0为中心点
#M = cv2.getRotationMatrix2D((100,100),15,1.0)
#中心点是(x,y),图像的正中心
#M = cv2.getRotationMatrix2D((w/2,h/2),15,1.0)
#整个窗口没变,图像变小了,变成整个窗口的0.3,参数,中心点,角度,缩放比例
#M = cv2.getRotationMatrix2D((w/2,h/2),15,0.3)
src = np.float32([[400,300],[800,300],[400,1000]])
dst = np.float32([[200,400],[600,500],[150,1100]])
M = cv2.getAffineTransform(src,dst)
#如果想要改变新图像的尺寸,需要修改dsize
#dst = cv2.warpAffine(lh,M,(lh.shape[1],lh.shape[0]))
new = cv2.warpAffine(lh,M,(int(w/2),int(h/2)))
cv2.imshow('lh',lh)
cv2.imshow('dst',new)
cv2.waitKey(0)
输出结果对比:
平移

代码注释
cv2.warpAffine(src, M, dsize)
src:输入图像
M:2×3 的变换矩阵
dsize:输出图像的尺寸(宽,高)。
1)平移
M = np.float32([[1, 0, 200], [0, 1, 300]])
矩阵含义:[1,0,tx]和[0,1,ty],其中tx是水平平移量(正右负左),ty是垂直平移量(正下负上)。
效果:图像沿 x 轴平移 200 像素,沿 y 轴平移 300 像素。
2)旋转 + 缩放
通过cv2.getRotationMatrix2D()生成旋转矩阵:
M = cv2.getRotationMatrix2D(center, angle, scale)
center:旋转中心点((x,y))
angle:旋转角度(正数为逆时针旋转,负数为顺时针)
scale:缩放因子(>1 放大,<1 缩小)
3)自定义反射变换
通过cv2.getAffineTransform(src, dst)生成变换矩阵,需要指定3 对对应点(原图像点src和变换后点dst):
src = np.float32([[400,300], [800,300], [400,1000]]) # 原图像中的3个点
dst = np.float32([[200,400], [600,500], [150,1100]]) # 变换后对应的3个点
M = cv2.getAffineTransform(src, dst) # 计算变换矩阵
原理:3 对对应点唯一确定一个仿射变换(因为 2×3 矩阵有 6 个未知数,3 个点提供 6 个方程)。
效果:根据 3 对点位关系,实现复杂的组合变换(可能同时包含旋转、平移、缩放、剪切)。
五,透视变换
透视变换是一种能够改变图像视角的几何变换,常用于校正图像的透视畸变(如倾斜拍摄的文档、建筑物等),核心是将 “3D 视角下的透视投影” 转换为 “2D 平面视图”。
透视变换的核心特点
打破平行性:与仿射变换不同,透视变换会改变图像中平行线的关系(例如,现实中平行的道路向远方交汇于一点),更贴近人眼的透视效果。
4 点确定变换:需要通过原图像和目标图像中的4 对对应点来唯一确定变换矩阵(仿射变换只需 3 对点)。
3×3 变换矩阵:透视变换通过一个 3×3 的矩阵(M)实现,对像素点(x,y)的变换公式为:
x' = (m00*x + m01*y + m02) / (m20*x + m21*y + m22)
y' = (m10*x + m11*y + m12) / (m20*x + m21*y + m22)
分母的存在是透视变换的关键,使其能模拟 “近大远小” 的透视效果。
#透视变换
import numpy as np
import cv2
img = cv2.imread('1.jpg')
#通过尝试找到四个角的坐标
src = np.float32([[100,1100],[2100,1100],[0,4000],[2500,3900]])
dst = np.float32([[0,0],[2300,0],[0,3000],[2300,3000]])
M =cv2.getPerspectiveTransform(src, dst)
new = cv2.warpPerspective(img,M,(2300,3000))
cv2.imshow('orgin',img)
cv2.imshow('new',new)
cv2.waitKey(0)
代码中的实现步骤:
透视变换主要通过两个函数完成:cv2.getPerspectiveTransform()生成变换矩阵,cv2.warpPerspective()应用变换。
输出结果:
代码注释
1)定义对应点对
src = np.float32([[100,1100], [2100,1100], [0,4000], [2500,3900]]) # 原图像中待校正区域的4个角点
dst = np.float32([[0,0], [2300,0], [0,3000], [2300,3000]]) # 目标图像中对应的4个角点(通常是矩形,如文档的正视图)
src:原图像中存在透视畸变的区域(如倾斜拍摄的矩形物体的四个角)。
dst:目标图像中矫正后的区域(通常是规则的矩形,确保四条边平行)。
2)计算透视变换矩阵
M = cv2.getPerspectiveTransform(src, dst) # 根据4对点计算3×3的变换矩阵M
3)应用透视变换
new = cv2.warpPerspective(img, M, (2300, 3000)) # 输出图像尺寸为(宽=2300, 高=3000)
dsize参数指定输出图像的宽和高,需与dst点定义的矩形尺寸匹配(否则会拉伸)。
与仿射变换的核心区别

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)