【Python图像处理篇】opencv中的仿射变换和透视变换

在这里插入图片描述

仿射变换可以将矩形图片映射为平行四边形,
透视变换可以将矩形图片映射为任意四边形。


前言

opencv提供了两个变换函数,cv2.warpAffine和cv2.warpPerspective,
使用这两个函数可以实现所有类型的变换。

cv2.warpAffine 接收的参数2x3的变换矩阵;

cv2.warpPerspective 接收的3x3的变换矩阵。


一、仿射变换 cv2.warpAffine()

1.1 函数说明

img_out = cv.warpAffine(img, mat, size)

@desc:
img_out -- 输出图像
img -- 原始图像
mat -- 2×3的变换矩阵
size -- 变换后图像尺寸
  1. 仿射变换(Affine Transformation) 包括平移(transform)、旋转(rotate)、缩放(scale)、剪切(shear)。
  2. 本质上是另外两种简单变换的叠加:一个是线性变换,一个是平移变换
  3. 该变换能保证图像的平直性和平行性,原来的直线仿射变换后还是直线,原来的平行线经过仿射变换之后还是平行线。
  4. 进行哪种形式的仿射变换完全取决于变换矩阵mat。

1.2 仿射变换实例

变换矩阵mat不同,变换类型不同

仿射变换矩阵mat的三种设定方式:

  1. 人为给定
  2. 使用函数 cv2.getRotationMatrix2D()
  3. 使用函数 cv2.getAffineTransform(src, dst)

1.2.1 平移变换

平移矩阵 mat_shift 为人为给定。

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

# ----------------------------------------------------#
#           读取图像
# ----------------------------------------------------#
image_original = cv.imread("LenaRGB.bmp")
H, W, _ = image_original.shape
cv.imshow("image_original", image_original)
cv.waitKey(delay=0)

# ----------------------------------------------------#
#           平移变换
# mat = [[1,0,dx],
#        [0,1,dy]]
# ----------------------------------------------------#
dx = 50
dy = 100
mat_shift = np.float32([[1, 0, dx],
                        [0, 1, dy]])  # 构造平移矩阵
image_shift = cv.warpAffine(image_original, mat_shift, (W, H))
cv.imshow("image_shift", image_shift)
cv.waitKey(delay=0)
cv.destroyAllWindows()

Lena图

1.2.2 旋转变换

旋转矩阵 mat_rotate 使用函数 cv2.getRotationMatrix2D() 获得。

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

# ----------------------------------------------------#
#           读取图像
# ----------------------------------------------------#
image_original = cv.imread("LenaRGB.bmp")
H, W, _ = image_original.shape
cv.imshow("image_original", image_original)
cv.waitKey(delay=0)

# ----------------------------------------------------#
#           旋转变换
# 对于图像的变换,OpenCV 提供了 getRotationMatrix2D() 函数来得到旋转矩阵
# 该函数包含三个参数,第一个参数是旋转中心,第二个参数是旋转角度,第三个参数是缩放比例
# mat = cv2.getRotationMatrix2D(center, angle, scale)
# ----------------------------------------------------#
center = (256, 256)
angle = 45
scale = 1
mat_rotate = cv.getRotationMatrix2D(center, angle, scale)
image_rotate = cv.warpAffine(image_original, mat_rotate, (W, H))
cv.imshow("image_rotate", image_rotate)
cv.waitKey(delay=0)
cv.destroyAllWindows()

Lena图

1.2.3 一般仿射变换

仿射矩阵 mat_affine 使用函数cv2.getAffineTransform() 获得。

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

# ----------------------------------------------------#
#           读取图像
# ----------------------------------------------------#
image_original = cv.imread("LenaRGB.bmp")
H, W, _ = image_original.shape
cv.imshow("image_original", image_original)
cv.waitKey(delay=0)

# ----------------------------------------------------#
#           仿射变换
# 变换矩阵mat可通过cv.getAffineTransfrom(points1, points2)函数获得
# 变换矩阵的获取需要至少三组变换前后对应的点坐标,设取原图上的三个点组成矩阵points1,变换后的三个点组成的矩阵points2
# mat_affine = cv.getAffineTransform(points1, points2)
# image_affine = cv.warpAffine(image_original, mat_affine, (image_original.shape[1], image_original.shape[0]))
# ----------------------------------------------------#
points1 = np.float32([[30, 30], [100, 40], [40, 100]])
points2 = np.float32([[60, 60], [200, 80], [80, 200]])
mat_affine = cv.getAffineTransform(points1, points2)
image_affine = cv.warpAffine(image_original, mat_affine, (W, H))
cv.imshow("image_affine", image_affine)
cv.waitKey(delay=0)
cv.destroyAllWindows()

在这里插入图片描述

1.3 仿射变换总结

  1. 在仿射变换中,原图中所有的平行线,在结果图像中仍然保持平行。
    为了得到仿射变换矩阵,需要从原图像中找到三个点以及在输出图像中的对应点。然后cv2.getAffineTransform()函数会创建一个2x3的矩阵,即为仿射变换矩阵。
    最后将矩阵传入函数cv2.warpAffine()对图像进行仿射变换。
  2. 仿射变换是一种二维坐标到二维坐标之间的线性变换,它保持了二维图形的平直性(直线经过变换之后依然是直线)和平行性(二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。
  3. 任意的仿射变换都能表示为乘一个矩阵(线性变换),再加上一个向量(平移)的形式。

二、透视变换 cv2.warpPerspective()

2.1 函数说明

img_out = cv.warpPerspective(img, mat, size)

@desc:
img_out -- 输出图像
img -- 原始图像
mat -- 3×3的变换矩阵
size -- 变换后图像尺寸
  1. 透视变换(Perspective Transformation) 也叫视角转换,是将图片投影到一个新的视平面,也称作投影映射。顾名思义,将图片从一个视角转换到另一个视角
  2. 该变换能保证图像的平直性,不保证平行性,透视变换可保持直线不变形,但是平行线可能不再平行。

2.2 透视变换实例

透视变换矩阵 mat_perspective 使用函数 cv.getPerspectiveTransform() 获得。

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

# ----------------------------------------------------#
#           读取图像
# ----------------------------------------------------#
image_original = cv.imread("LenaRGB.bmp")
H, W, _ = image_original.shape
cv.imshow("image_original", image_original)
cv.waitKey(delay=0)

# ----------------------------------------------------#
#           透视变换
# 变换矩阵mat可通过cv.getPerspectiveTransform()函数获得,原理和cv.getAffineTransform()相同
# 透视变换至少需要四组变换前后对应的点坐标
# 设取原图上的四个点组成矩阵points1,变换后的四个点组成的矩阵points2
# mat_perspective = cv.getPerspectiveTransform(points1, points2)
# image_perspective = cv.warpPerspective(image_original, mat_perspective, (image_original.shape[1], image_original.shape[0]))
# ----------------------------------------------------#
points1 = np.float32([[30, 30], [10, 40], [40, 10], [5, 15]])
points2 = np.float32([[0, 0], [400, 0], [0, 400], [400, 400]])

mat_perspective = cv.getPerspectiveTransform(points1, points2)
image_perspective = cv.warpPerspective(image_original, mat_perspective,
                                       (image_original.shape[1], image_original.shape[0]))

cv.imshow("image_perspective", image_perspective)
cv.waitKey(delay=0)
cv.destroyAllWindows()

在这里插入图片描述

2.3 透视变换总结

  1. 对于视角变换,需要一个3x3的变换矩阵。
    为了得到视角变换(透视变换)矩阵,需要在输入图像上找四个点,以及在输出图像上对应的位置。这四个点中的任意三个都不能共线。
    然后函数cv2.getPerspectiveTransform()创建一个3x3的矩阵,即为视角变换矩阵。
    最后将矩阵传入函数cv2.warpPerspective对图像进行透视变换。
  2. 视角变换是二维到三维,再到另一个二维视平面的映射。
  3. 相对于仿射变换,视角变换灵活性更高,将一个四边形矩形区域映射到另一个四边形区域(不一定是平行四边形),不只是线性变换,但也是通过矩阵乘法实现的,使用的是3x3的矩阵,矩阵前两行和仿射矩阵相同,也实现了线性变换和平移,第三行用于实现透视变换。

三、单应性变换cv2.findHomography()

参考单应性cv.findHomography 相关的:
OpenCV中的「透视变换 / 投影变换 / 单应性」—cv.warpPerspective、cv.findHomography
单应性矩阵可以当作透视变换中的透视变换矩阵mat 。

四、总结

  1. 仿射变换可以将矩形图片映射为平行四边形,
    透视变换可以将矩形图片映射为任意四边形。

  2. 仿射变换是透视变换的一种特殊形式,它是把二维转到三维,变换后在映射回之前的二维空间,而不是另一个二维空间。
  3. 仿射变换至少需要三个对应的点坐标,透视变换至少需要四个。

参考链接:
cv2.warpAffine、cv2.warpPerspective
cv2.getPerspectiveTransform()与cv2.warpPerspective()详解
python之详细图像仿射变换讲解(图像平移、旋转、缩放、翻转)
透视变换(Perspective Transformation)

  • 21
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在PythonOpenCV,寻找最佳缝合线的代码无需融合,是指在图像拼接的过程,不需要进行图像的融合操作。 一般情况下,图像拼接的过程分为三个主要步骤:特征提取、特征匹配和图像拼接。 特征提取阶段可以利用SIFT、SURF等算法来获取关键点和对应的描述子,获得图像有意义的特征点。 特征匹配阶段使用匹配算法(例如FLANN或Brute-Force)来找到匹配的特征点对,确定两幅图像之间的相对位置关系。 图像拼接阶段则根据匹配的特征点对,使用透视变换(perspective transformation)来将图像对齐,并将多个图像拼接在一起。 在上述过程,并未涉及到图像融合的操作。图像拼接后,相邻图像的边缘会存在不连续的情况,这样的缝隙可以通过后续处理来进行混合或者修复。 但如果我们只需要得到多个图像的拼接结果而不进行图像的融合,可以跳过图像融合的步骤,直接输出每个图像的拼接结果。 简而言之,PythonOpenCV最佳缝合线的代码无需融合,只需进行特征提取、特征匹配和图像拼接等基本操作即可。 ### 回答2: 在PythonOpenCV,最佳缝合线的代码无需融合,是指在进行图像拼接时,我们只关注如何找到最佳的拼接位置和拼接线,而不去实际进行像素值的融合。 首先,我们需要使用OpenCV的SIFT或SURF算法来提取关键点和特征描述子。然后,通过匹配两张图片的特征点,可以得到一些匹配对。接下来,我们可以通过RANSAC或LMEDS算法去消除错误匹配点对,得到稳定的匹配对。 然后,我们通过计算匹配对之间的几何变换矩阵,如仿射变换或投影变换,来估计两张图片之间的几何变换关系。利用这个变换关系,我们可以将第二张图片根据前一张图片的坐标系统进行变换,使其与第一张图片对齐。 接着,我们需要找到最佳的拼接位置和拼接线。这可以通过计算两张图片之间的重叠区域,并根据某种准则(如最小化重叠区域内的差异)来确定最佳拼接位置和拼接线的位置。 最后,我们可以通过在拼接位置处进行图片融合来实现平滑过渡,从而得到无缝的拼接结果。但在本题要求不进行融合处理,所以只需找到最佳的拼接线和拼接位置即可。 总而言之,在PythonOpenCV实现最佳缝合线的代码无需融合,我们需要提取关键点和特征描述子,进行特征点匹配,估计两张图片之间的几何变换关系,计算重叠区域并确定最佳拼接线和拼接位置。 ### 回答3: 在Python OpenCV寻找最佳缝合线的代码无需融合过程,可以通过以下几个步骤完成。 首先,加载两幅待拼接的图像。可以使用OpenCV的imread函数读取图像数据,并使用imread得到的图像数据进行后续处理。 接下来,使用SIFT或SURF等特征提取器检测两幅图像的特征点。可以使用OpenCV的xfeatures2d模块提供的SIFT或SURF算法。 然后,通过特征匹配算法(如FLANN或BFMatcher等)找到两幅图像对应的特征点并进行匹配。可以使用OpenCV的xfeatures2d模块提供的FLANN或BFMatcher算法。 在得到匹配特征点后,可以使用RANSAC算法去除错误的匹配点。使用OpenCV的findHomography函数根据匹配点估计变换矩阵。 然后,通过变换矩阵对其一幅图像进行透视变换,将其与另一幅图像进行拼接。使用OpenCVwarpPerspective函数实现透视变换。 最后,可以将拼接后的图像保存为新的文件或显示在屏幕上。使用OpenCV的imwrite函数保存图像,或使用imshow函数显示图像。 需要注意的是,最佳缝合线的概念是相对的,需要根据具体情况进行调整和优化。以上是一个简化的拼接图像的流程,实际应用可能需要更多的步骤和参数调节,以得到更好的拼接效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值