文章目录
- 仿射变换介绍
- 仿射变换 python 实现——cv2.warpAffine
- 透视变换
- 透视变换 python 实现——cv2.warpPerspective
- 牛刀小试
- 各类变换的区别与联系
- 仿射变换和单应性矩阵
- 透视变换和单应性矩阵
仿射变换介绍
仿射变换(Affine Transformation),又称仿射映射,是在几何学中描述的一个向量空间进行线性变换后,再附加一个平移变换,从而映射到另一个向量空间的过程。以下是对仿射变换的详细解释:
-
定义:
仿射变换是一个向量空间到另一个向量空间的映射,该映射由一个非奇异的线性变换(通过一次函数进行)和一个平移变换组成。
在有限维的情况下,每个仿射变换可以由一个矩阵A和一个向量b给出,形式为A和一个附加的列b。 -
数学表示:
仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的矩阵乘法,但要加上一个特定的扩展矩阵。
仿射变换在数学上可以通过齐次坐标矩阵表示,其中包含一个平移向量。 -
特性:
仿射变换保持了二维图形的 “平直性”,即变换后直线仍然是直线。
仿射变换也保持了“平行性”,即变换后平行线仍然是平行线,且直线上点的位置顺序不变。 -
应用:
仿射变换在计算机图形学、计算机视觉和图像处理等领域有着广泛的应用,如图像配准、图像纠正、纹理纠正以及创建全景图像等。 -
组成:
仿射变换可以包含多种几何变换的组合,如平移、旋转、缩放(dilation)和剪切(shear)等。 -
实现:
在图像处理中,如OpenCV这样的库提供了仿射变换的实现函数,如cv2.warpAffine(),它通过一个变换矩阵(映射矩阵)M来实现图像的仿射变换。 -
几何意义:
仿射变换可以理解为一系列的原子变换(如平移、旋转、尺度变换等)的复合实现。
总结来说,仿射变换是一种强大的几何变换工具,它能够在保持图形基本形状特性的同时,实现图像的多种变换操作。
仿射变换 python 实现——cv2.warpAffine
OpenCV 库中 cv2.warpAffine 用于对图像进行仿射变换。以下是 cv2.warpAffine 函数的中文文档,详细解释了其参数、用法和原理。
一、函数原型
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
二、参数说明
-
src:
类型:InputArray
说明:输入图像,即待变换的图像。 -
M:
类型:InputArray
说明:2x3的变换矩阵,它定义了仿射变换的类型。通常,这个矩阵由cv2.getAffineTransform或cv2.getRotationMatrix2D等函数计算得到。
矩阵形式:
[a, b, c]
[d, e, f]
其中,a和e控制缩放,b和d控制旋转和剪切,c和f控制平移。 -
dsize:
类型:Size
说明:输出图像的大小,即变换后图像的尺寸。 -
dst:
类型:OutputArray
说明:输出图像,可选参数。如果提供,函数将把结果写入这个图像;否则,将创建一个新的图像。 -
flags:
类型:int
说明:插值方法的标识符。默认为cv2.INTER_LINEAR(双线性插值)。其他可用的选项包括cv2.INTER_NEAREST(最近邻插值)、cv2.INTER_AREA(区域插值)、cv2.INTER_CUBIC(双三次插值)等。 -
borderMode:
类型:int
说明:边界填充方式。默认为cv2.BORDER_CONSTANT(常量填充)。其他可用的选项包括cv2.BORDER_REPLICATE(复制填充)、cv2.BORDER_REFLECT(反射填充)等。 -
borderValue:
类型:Scalar
说明:如果边界模式为cv2.BORDER_CONSTANT,这个值表示用于填充的边界颜色值。默认为0(黑色)。
三、函数作用
cv2.warpAffine 函数通过对输入图像 src 应用一个仿射变换矩阵 M,生成一个输出图像 dst。仿射变换可以包括旋转、缩放、平移、倾斜等操作,是计算机视觉中常用的图像变换方法。
四、注意事项
变换矩阵 M 必须是一个2x3的矩阵,且矩阵中的值会影响变换的效果。
输出图像 dst 的大小 dsize 可以是任意大小,但通常建议与输入图像 src 的大小相近或相同,以避免不必要的图像失真。
插值方法 flags 的选择会影响变换后图像的质量,需要根据具体需求选择合适的插值方法。
边界填充方式 borderMode 和填充值 borderValue 主要用于处理变换后图像边界的像素值,需要根据实际情况设置。
透视变换
透视变换(Perspective Transformation)是一种二维坐标到三维坐标再到另一个二维坐标的映射,它利用透射中心、像点、目标点三点共线的条件,将图片投影到一个新的视平面,同时保持承影面上投影几何图形的不变性。以下是透视变换的详细介绍:
一、变换原理
二维到三维再到二维:透视变换首先将二维图像坐标转换到三维空间,然后再从三维空间映射到另一个二维平面。
保持几何图形不变:尽管图像经历了从二维到三维再到二维的转换,但透视变换能够确保承影面上的投影几何图形保持不变。
二、变换矩阵
透视变换的通用公式中涉及一个变换矩阵,通常是一个3x3的矩阵。这个矩阵可以分解为三个部分:
T1:对图像进行线性变换(如缩放、旋转)。
T2:对图像进行平移。
T3:通常设为1,表示对图像进行投射变换。
三、应用场景
透视变换在多个领域都有广泛的应用,包括但不限于:
文档扫描与校正:通过逆透视变换,可以校正扫描文档中的透视畸变,使其恢复到正常的平面状态。
视频监控与图像识别:在视频监控中,摄像机的视角和位置可能导致图像的透视变换。透视变换可以校正这种变换,以准确还原目标物体的形状和位置。在图像识别中,透视变换可用于图像配准,即将多幅图像进行对齐。
虚拟现实与增强现实:透视变换可以用于将虚拟场景与真实场景进行融合,或者将虚拟内容叠加到真实场景中,提供沉浸式体验。
平面投影与立体重建:在平面投影中,透视变换可以将三维场景的立体图像投影到二维平面上。在立体重建中,它可以通过对多幅图像进行透视校正,恢复出三维场景的真实形状和位置。
图像拼接与全景摄影:透视变换在图像拼接中用于将多幅图像进行对齐和融合,以创建全景图像。
四、与仿射变换的区别
透视变换是仿射变换的延续,仿射变换是透视变换的一种特殊形式。仿射变换保持了二维图形的“平直性”和“平行性”,即直线变换之后依然是直线,平行线依然是平行线。而透视变换提供了更大的灵活性,可以将一个四边形区域映射到另一个四边形区域。
五、 总结
透视变换是一种强大的图像变换工具,它通过将图像投影到新的视平面来保持几何图形的不变性。它在多个领域都有广泛的应用,特别是在需要校正图像中的透视畸变或进行图像配准的场景中。
透视变换 python 实现——cv2.warpPerspective
cv2.warpPerspective 是 OpenCV 库中的一个函数,用于实现图像的透视变换。透视变换能够将一个图像映射到一个新的视平面上,并且保持图像的直线性和平行性。下面是对 cv2.warpPerspective 函数的中文文档,清晰分点表示并归纳相关信息:
一、函数原型
cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
二、参数
-
src
类型:InputArray
说明:输入图像,即待进行透视变换的原始图像。 -
M
类型:InputArray
说明:3x3 的变换矩阵。这个矩阵通常由 cv2.getPerspectiveTransform 函数计算得到,描述了从原始图像到目标图像的映射关系。 -
dsize
类型:Size 或 (int, int) 元组
说明:输出图像的尺寸,以 (width, height) 的形式给出。 -
dst (可选)
类型:OutputArray
说明:输出图像,即透视变换后的图像。如果提供,函数将结果写入这个图像;否则,将创建一个新的图像。 -
flags (可选)
类型:int
说明:插值方法的标识符。它决定了如何计算输入图像和输出图像之间的像素值关系。常用的插值方法包括:
cv2.INTER_LINEAR:双线性插值(默认)
cv2.INTER_NEAREST:最近邻插值
cv2.INTER_AREA:使用像素区域关系进行重采样
cv2.INTER_CUBIC:双三次插值 -
borderMode (可选)
类型:int
说明:边界像素的插值方法。如果目标图像中的像素在原始图像之外,则根据此参数指定如何填充这些像素。常见的边界模式包括:
cv2.BORDER_CONSTANT:使用常数值填充边界
cv2.BORDER_REPLICATE:复制边界像素
cv2.BORDER_REFLECT:反射边界像素 -
borderValue (可选)
类型:Scalar
说明:如果边界模式为 cv2.BORDER_CONSTANT,则指定用于填充边界的常数颜色值。默认为黑色(0)。
三、函数作用
cv2.warpPerspective 函数将输入图像 src 根据给定的透视变换矩阵 M 进行透视变换,并将结果保存到输出图像 dst 中。该函数在图像校正、图像拼接、目标跟踪等计算机视觉任务中广泛应用。
使用示例
python
import cv2
import numpy as np
# 读取图像
img = cv2.imread('input.jpg')
# 定义源图像和目标图像上的四个点
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
# 计算透视变换矩阵
M = cv2.getPerspectiveTransform(pts1,pts2)
# 设置输出图像大小
dsize = (300, 300)
# 进行透视变换
dst = cv2.warpPerspective(img, M, dsize)
# 显示图像
cv2.imshow('Input', img)
cv2.imshow('Output', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、注意事项
变换矩阵 M 必须是一个 3x3 的矩阵,通常由 cv2.getPerspectiveTransform 计算得到。
插值方法 flags 和边界模式 borderMode 的选择会影响变换后图像的质量和边界像素的填充方式,应根据实际需求进行选择。
如果 dst 不为空,则 cv2.warpPerspective 会将结果写入 dst;否则,会创建一个新的图像。
透视变换通常用于校正图像的透视畸变,或者将一个物体从不同的视角投影到一个平面上。
牛刀小试
参考学习来自 【opencv实践】仿射变换和透视变换
import cv2
import numpy as np
srcImage = cv2.imread("./1.png")
road_w = 540
road_h = 850
imgPts = np.float32([[58, 462],
[1007, 462],
[440, 299],
[639, 299],
])
objPts = np.float32([[50, 780],
[490, 780],
[50, 150],
[490, 150]])
M = cv2.getPerspectiveTransform(imgPts, objPts)
print(M)
dstImage = cv2.warpPerspective(srcImage, M, (road_w, road_h))
"draw points"
for i in range(4):
cv2.circle(srcImage, center=(int(imgPts[i][0]), int(imgPts[i][1])), radius=5, color=[0, 0, 255], thickness=-1)
cv2.circle(dstImage, center=(int(objPts[i][0]), int(objPts[i][1])), radius=5, color=[255, 0, 0], thickness=-1)
"draw line"
for i in range(0, 4, 2):
cv2.line(srcImage, pt1=(int(imgPts[i][0]), int(imgPts[i][1])), pt2=(int(imgPts[i+1][0]), int(imgPts[i+1][1])),
color=[0, 0, 255], thickness=5, lineType=cv2.LINE_AA)
cv2.line(dstImage, pt1=(int(objPts[i][0]), int(objPts[i][1])), pt2=(int(objPts[i+1][0]), int(objPts[i+1][1])),
color=[255, 0, 0], thickness=5, lineType=cv2.LINE_AA)
"show"
cv2.imshow("source", srcImage)
cv2.imshow("perspective", dstImage)
# cv2.imwrite("source.jpg", srcImage)
# cv2.imwrite("perspective.jpg", dstImage)
cv2.waitKey(0)
cv2.destroyAllWindows()
输入图像
选取四个点
[58, 462],
[1007, 462],
[440, 299],
[639, 299],
设定四个点仿射变换后的坐标
[50, 780],
[490, 780],
[50, 150],
[490, 150]
获取透视变换矩阵
[[-3.73905835e-01 -1.07177303e+00 4.76523333e+02]
[-2.25793124e-16 -3.70345076e+00 1.08196566e+03]
[-0.00000000e+00 -3.91005823e-03 1.00000000e+00]]
透视变换
各类变换的区别与联系
仿射变换和单应性矩阵
我就看看看看的回答
gamemonkey的回答
透视变换和单应性矩阵
来自 基础矩阵、本质矩阵、单应性矩阵、透视变换、仿射变换
单应性矩阵:在两视几何中,可以这样理解,两架相机拍同一空间上得到两幅图像AB,其中一幅A在另一幅B存在一种变换而且是一一对应的关系,他们之间可以用矩阵表示 这个矩阵用单应矩阵
仿射变换affine是透视变换的子集,透视变换是通过homography单应矩阵实现的