opencv-python学习笔记7-几何变换

目录

一、几何变换基础:

(1)图像平移(Translation):

原理:

公式推导:

过程:

OpenCV变换过程:

(2)图像旋转(Rotation):

原理:

公式推导:

过程:

(3)仿射变换(Affine Transformation):

原理:

公式推导:

参数:

注意事项:

(4)图像放缩(Scaling):

原理:

公式推导:

参数:

注意事项:

二、图像平移: 

(1)作用:

(2)方法:

(3)函数原型:

(4)参数:

(5)注意事项:

(6)使用示例:

三、图像旋转: 

(1)作用:

(2)方法:

(3)函数原型:

(4)参数:

(5)注意事项:

(6)使用示例:

四、仿射变换:

(1)作用:

(2)方法:

(3)函数原型:

(4)参数:

(5)注意事项:

(6)使用示例:

 五、OpenCV中的放缩:

(1)作用:

(2)方法:

(3)函数原型:

(4)参数:

(5)注意事项:

(6)使用示例:

 六、插值方法:

(1)最近邻插值(Nearest Neighbor Interpolation):

(2)双线性插值(Bilinear Interpolation):

(3)双三次插值(Bicubic Interpolation):

(4)三次样条插值(Cubic Spline Interpolation):

(5)Lanczos插值:

(6)区域插值(Area Interpolation):


一、几何变换基础:

几何变换是图像处理中用于改变图像几何形状的一系列操作。它们通常用于校正图像、创建视觉效果或者为进一步的图像分析做准备。

(1)图像平移(Translation):

图像平移是几何变换中最简单的一种,它涉及到将图像中的每个像素点按照一定的向量移动。在二维空间中,如果我们有一个点 (x,y) ,我们想要将它平移到 (x′,y′) ,这个过程可以通过一个平移向量 (tx​,ty​) 来实现。

原理:

图像平移的基本原理是将图像中的每个像素点根据平移向量移动一定的距离。平移向量 (tx​,ty​) 指定了在x轴和y轴方向上的移动距离。平移操作不改变图像中像素点之间的相对位置,也不改变像素值。

公式推导:

对于一个原始图像中的点 (x,y) ,平移后的点 (x′,y′) 可以通过以下公式得到:

其中:

  • x′和 y′是平移后点的坐标。
  • tx和 ty是平移向量的分量,分别表示在x轴和y轴方向上的平移距离。

这个变换可以用一个2x3的矩阵来表示,称为平移矩阵:

在图像处理库如OpenCV中,通常使用仿射变换来实现平移,即使用一个2x3的矩阵与图像坐标进行矩阵乘法。对于一个点 (x,y) ,平移后的坐标可以通过以下矩阵乘法得到:

过程:
  • 定义平移向量:首先确定你想要在x轴和y轴方向上移动图像的距离 txtx​ 和 tyty​ 。

  • 构造平移矩阵:使用这些值构造一个2x3的平移矩阵。

  • 应用平移矩阵:对于图像中的每个像素点,将其坐标表示为齐次坐标(即 (x,y,1)(x,y,1) ),然后与平移矩阵相乘,得到新的坐标。

  • 插值:由于平移可能会导致新的坐标不是整数,因此需要使用插值方法来计算新位置的像素值。常用的插值方法包括最近邻插值、双线性插值等。

  • 生成新图像:使用插值后的坐标值生成新图像。

  • 通过这个过程,图像就被平移了指定的距离,而图像内容和像素值保持不变。

OpenCV变换过程:
  • 创建一个平移矩阵。
  • 使用warpAffine函数应用平移矩阵。
M = np.float32([[1, 0, tx], [0, 1, ty]])  # 平移矩阵
translated = cv2.warpAffine(src, M, (width, height))

(2)图像旋转(Rotation):

图像旋转是将图像围绕某一点旋转特定角度的几何变换。在二维空间中,图像旋转可以通过旋转矩阵来实现。以下是图像旋转的公式推导过程及原理。

原理:

图像旋转的基本原理是将图像中的每个像素点绕着旋转中心按照指定的角度进行旋转。这个过程保持图像中像素点之间的相对距离不变,但会改变像素点在图像坐标系中的位置。

公式推导:

假设我们有一个点P(x,y) 要绕着旋转中心 C(cx,cy)旋转 θ 角度。旋转后的点P′(x′,y′) 可以通过以下步骤得到:

  • 将点平移到旋转中心:首先将点 P 平移到坐标原点,即计算点 P相对于旋转中心 C 的坐标:

  • 应用旋转矩阵:然后应用二维旋转矩阵 R(θ)来计算旋转后的坐标:

  • 将点平移回原位置:最后将旋转后的点 P′′平移到原来的坐标系中:

过程:
  • 确定旋转中心和角度:首先确定旋转中心 C(cx,cy)C(cx,cy) 和旋转角度 θθ 。角度 θθ 可以是度或弧度,如果使用度,需要转换为弧度进行计算。

  • 构造旋转矩阵:使用旋转角度 θθ 构造二维旋转矩阵 R(θ)R(θ) 。

  • 应用旋转矩阵:对于图像中的每个像素点,将其坐标转换为相对于旋转中心的坐标,然后应用旋转矩阵,最后将坐标转换回原始坐标系。

  • 插值:由于旋转可能会导致新的坐标不是整数,因此需要使用插值方法来计算新位置的像素值。常用的插值方法包括最近邻插值、双线性插值、三次样条插值等。

  • 生成新图像:使用插值后的坐标值生成新图像。

  • 通过这个过程,图像就被绕着指定的旋转中心旋转了指定的角度,而图像内容和像素值保持不变。在实际应用中,还需要考虑旋转后图像的边界处理,可能需要对图像进行适当的缩放或填充以避免图像信息的丢失。

OpenCV变换过程:

  • 计算旋转矩阵。
  • 使用getRotationMatrix2D获取旋转矩阵。
  • 使用warpAffine函数应用旋转矩阵。
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(src, M, (width, height))

(3)仿射变换(Affine Transformation):

原理:

仿射变换是一种二维坐标到二维坐标之间的线性变换,它保持了图像中直线的平行性。这意味着,经过仿射变换后,原本平行的线仍然保持平行。仿射变换包括了旋转、缩放、剪切和平移等操作,这些操作可以组合使用以实现复杂的几何变换。

公式推导:

在二维空间中,一个点 P(x,y)经过仿射变换后变为 P′(x′,y′)。这个变换可以用一个2x3的矩阵 A 来表示,加上一个平移向量t来完成:

这里,a,b,c,d表示线性变换部分,而 tx,ty表示平移向量。

参数:
  • a,b,c,d:线性变换参数,可以表示旋转、缩放和剪切。
  • tx​,ty​:平移向量,表示在x轴和y轴方向上的平移距离。
注意事项:
  • 仿射变换不保持角度和长度,但保持平行性。
  • 在实际应用中,需要确保变换后的图像尺寸足够大,以包含所有变换后的像素点。
  • 插值方法的选择对图像质量有重要影响,常用的插值方法包括最近邻插值、双线性插值等。

OpenCV变换过程:

  • 选择三个点及其对应的目标位置。
  • 使用getAffineTransform获取仿射变换矩阵。
  • 使用warpAffine函数应用仿射变换矩阵。
M = cv2.getAffineTransform(srcTri, dstTri)
affine = cv2.warpAffine(src, M, (width, height))

(4)图像放缩(Scaling):

原理:

图像放缩是一种基本的图像处理操作,用于改变图像的尺寸,可以是等比例放缩(各向同性),也可以是不等比例放缩(各向异性)。放缩操作通过改变图像中像素点的间隔来实现,从而改变图像的分辨率。

公式推导:

假设原始图像的坐标为 (x,y),放缩后的图像坐标为(x′,y′) 。放缩操作可以通过以下公式表示:

其中,sx和 sy​ 分别是沿 x 轴和 y 轴的放缩比例因子。对于等比例放缩,sx​=sy​ 。

在齐次坐标下,放缩变换可以用一个 3x3 的矩阵表示:

这个矩阵乘法表示了原始坐标 (x,y)经过放缩变换后得到的新坐标(x′,y′) 。

参数:
  • sx,sy:放缩比例因子,决定了图像在 x 轴和 y 轴方向上的缩放程度。
注意事项:
  • 放缩操作可能会导致图像失真,特别是不等比例放缩时。
  • 选择合适的插值方法对放缩后的图像质量有重要影响。常见的插值方法包括最近邻插值、双线性插值、双三次插值等。
  • 放缩后的图像尺寸应该是整数,可能需要对放缩比例进行适当的四舍五入。

OpenCV变换过程:

  • 计算新的图像尺寸。
  • 使用resize函数进行放缩。
resized = cv2.resize(src, None, fx=scale_x, fy=scale_y, 
interpolation=cv2.INTER_LINEAR)
  • 在进行几何变换时,通常需要选择合适的插值方法来填充新位置的像素值。OpenCV提供了多种插值方法,如最近邻插值(cv2.INTER_NEAREST)、线性插值(cv2.INTER_LINEAR)、立方插值(cv2.INTER_CUBIC)等。选择合适的插值方法可以提高变换后图像的质量。

二、图像平移: 

(1)作用:

图像平移是将整个图像在坐标平面内沿着某一方向移动一定距离。

这种变换通常用于:

  • 校正图像的对齐。
  • 调整图像在框架中的位置。
  • 创建动画效果。

(2)方法:

图像平移通常通过构造一个仿射变换矩阵来实现,该矩阵描述了图像平移的参数。

(3)函数原型:

在OpenCV中,图像平移可以通过warpAffine函数实现,其函数原型如下:

dst = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
  • src:输入图像。
  • M:2x3的变换矩阵。
  • dsize:输出图像的大小(宽度,高度)。
  • dst:输出图像。
  • flags:插值方法,默认是cv2.INTER_LINEAR
  • borderMode:边界填充方式,默认是cv2.BORDER_CONSTANT
  • borderValue:边界填充值,默认是0。

(4)参数:

  • M:变换矩阵,对于平移变换,矩阵形式为:
    np.float32([[1, 0, tx], [0, 1, ty]])
    其中txty分别是沿x轴和y轴的平移距离。
  • dsize:输出图像的大小,通常与输入图像相同或稍大,以确保所有内容都包含在内。

(5)注意事项:

  • 确保输出图像的尺寸足够大,以包含平移后的图像。
  • 插值方法会影响图像质量,cv2.INTER_LINEARcv2.INTER_NEAREST是常用的插值方法。
  • 边界填充方式和填充值会影响图像边缘的外观。

(6)使用示例:

import cv2
import numpy as np

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")

# 设置平移距离
tx = 50  # x轴平移距离
ty = 25  # y轴平移距离

# 创建平移矩阵
translation_matrix = np.float32([[1, 0, tx], [0, 1, ty]])

# 获取图像尺寸
height, width = image.shape[:2]

# 应用平移变换
translated_image = cv2.warpAffine(image, translation_matrix, (width, height))

# 显示原图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Translated Image', translated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 首先读取了一张图像,然后定义了沿x轴和y轴的平移距离。接着,创建一个平移矩阵,并使用warpAffine函数应用这个变换。最后,显示原始图像和变换后的图像。

三、图像旋转: 

(1)作用:

图像旋转是将图像围绕某一点(通常是图像中心或某个角点)旋转特定角度。

这种变换用于:

  • 校正图像的方向。
  • 创建视觉效果或动画。
  • 模拟视角变化。

(2)方法:

图像旋转可以通过多种方法实现,包括直接使用旋转矩阵或使用特定的图像处理库函数。

(3)函数原型:

在OpenCV中,图像旋转通常使用getRotationMatrix2DwarpAffine函数结合实现,函数原型如下:

M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(src, M, dsize, 
flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
  • getRotationMatrix2D:计算旋转变换矩阵。
    • center:旋转中心点。
    • angle:旋转角度,正值表示顺时针旋转。
    • scale:旋转时的缩放比例,默认为1.0。
  • warpAffine:应用仿射变换矩阵进行图像变换。

(4)参数:

  • center:旋转中心点,通常为图像的中心点。
  • angle:旋转角度。
  • scale:缩放比例,用于控制旋转时图像的大小变化。
  • dsize:输出图像的大小(宽度,高度)。
  • flags:插值方法,如cv2.INTER_LINEARcv2.INTER_NEAREST
  • borderMode:边界填充方式,如cv2.BORDER_CONSTANT

(5)注意事项:

  • 旋转角度应适当选择,以避免图像信息丢失。
  • 旋转可能导致图像部分区域超出原始图像边界,需要适当调整输出图像大小或填充边界。
  • 插值方法和边界填充方式会影响旋转后图像的质量。

(6)使用示例:

import cv2

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")

# 设置旋转参数
center = (image.shape[1] // 2, image.shape[0] // 2)  # 旋转中心
angle = 45  # 旋转角度
scale = 1.0  # 缩放比例

# 计算旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)

# 计算旋转后的图像大小
cos = np.abs(rotation_matrix[0, 0])
sin = np.abs(rotation_matrix[0, 1])
new_w = int((image.shape[0] * sin) + (image.shape[1] * cos))
new_h = int((image.shape[0] * cos) + (image.shape[1] * sin))
rotation_matrix[0, 2] += (new_w / 2) - center[0]
rotation_matrix[1, 2] += (new_h / 2) - center[1]

# 应用旋转变换
rotated_image = cv2.warpAffine(image, rotation_matrix, (new_w, new_h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)

# 显示原图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Rotated Image', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  •  首先读取了一张图像,然后定义旋转中心、角度和缩放比例。接着,计算旋转矩阵,并调整矩阵以确保旋转后的图像中心与原图中心对齐。然后,计算旋转后图像的新大小,并使用warpAffine函数应用了旋转变换。最后,显示原始图像和旋转后的图像。

四、仿射变换:

(1)作用:

仿射变换是一种二维图像变换,它保持了图像中直线的平行性。这种变换可以用于:

  • 图像校正,如矫正透视失真。
  • 图像编辑,如倾斜、缩放和旋转的组合。
  • 特征提取,如在图像识别中对齐图像。

(2)方法:

仿射变换可以通过构造一个2x3的变换矩阵来实现,该矩阵描述了图像的线性变换和位移。

(3)函数原型:

在OpenCV中,仿射变换通常使用getAffineTransformwarpAffine函数结合实现,函数原型如下:

M = cv2.getAffineTransform(srcTri, dstTri)
transformed = cv2.warpAffine(src, M, dsize, 
flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
  • getAffineTransform:计算仿射变换矩阵。
    • srcTri:源图像上的三个点。
    • dstTri:目标图像上的三个点。
  • warpAffine:应用仿射变换矩阵进行图像变换。

(4)参数:

  • srcTri:源图像上的三个点,通常是一个包含三个二维点的数组。
  • dstTri:目标图像上的三个点,与源图像上的点相对应。
  • M:仿射变换矩阵。
  • dsize:输出图像的大小(宽度,高度)。
  • flags:插值方法,如cv2.INTER_LINEARcv2.INTER_NEAREST
  • borderMode:边界填充方式,如cv2.BORDER_CONSTANT

(5)注意事项:

  • 选择的三个点必须不是共线的,否则无法计算仿射变换矩阵。
  • 插值方法会影响变换后图像的质量,cv2.INTER_LINEAR是常用的插值方法。
  • 边界填充方式和填充值会影响图像边缘的外观。

(6)使用示例:

import cv2
import numpy as np

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")

# 定义源图像上的三个点
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])

# 定义目标图像上的三个点
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])

# 计算仿射变换矩阵
M = cv2.getAffineTransform(pts1, pts2)

# 应用仿射变换
transformed_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

# 显示原图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Affine Transformed Image', transformed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 首先读取一张图像,然后定义源图像上的三个点和目标图像上的三个点。接着,计算仿射变换矩阵,并使用warpAffine函数应用这个变换。最后,显示原始图像和变换后的图像。

 五、OpenCV中的放缩:

(1)作用:

图像放缩是改变图像尺寸的过程,可以是单独改变高度或宽度,也可以同时按比例调整图像大小。这项技术在图像处理中非常重要,用于适应不同的显示需求或进行图像分析前的预处理。

(2)方法:

图像放缩可以通过OpenCV库中的cv2.resize()函数实现,该函数提供了多种插值方法来控制放缩质量。

(3)函数原型:

在Python中,cv2.resize()函数的原型如下:

dst = cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
  • src:输入图像。
  • dsize:输出图像的尺寸,格式为(width, height)。
  • fxfy:沿x轴和y轴的缩放比例。
  • interpolation:插值方法,默认为cv2.INTER_LINEAR

(4)参数:

  • dsize:指定缩放后的图像尺寸。
  • fxfy:指定缩放的比例因子,允许非整数尺寸放缩。
  • interpolation:插值方法,常见的有:
    • cv2.INTER_NEAREST:最近邻插值。
    • cv2.INTER_LINEAR:双线性插值。
    • cv2.INTER_AREA:使用像素区域关系进行重采样,适合缩小图像。
    • cv2.INTER_CUBIC:4x4像素邻域的双三次插值,较慢但效果好。

(5)注意事项:

  • 当使用fxfy时,dsize应设置为(0, 0)
  • 插值方法选择对图像质量有显著影响,通常缩小图像时使用INTER_AREA,放大图像时使用INTER_CUBICINTER_LINEAR
  • 确保输入图像有效,且尺寸与期望的输出尺寸相匹配。

(6)使用示例:

import cv2
# 读取图像
img = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")
# 指定缩放后的尺寸
resized_img = cv2.resize(img, (800, 600), interpolation=cv2.INTER_LINEAR)
# 使用缩放比例
scale_percent = 50  # 缩放比例为50%
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
resized_img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
# 显示原图和缩放后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Resized Image', resized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 首先读取一张图像,然后使用cv2.resize()函数将其尺寸调整为800x600像素。接着,使用缩放比例将图像缩小为原尺寸的50%,并使用INTER_AREA插值方法。最后,显示原始图像和缩放后的图像。

 六、插值方法:

插值方法在图像处理中非常重要,尤其是在进行图像缩放、旋转或任何形式的几何变换时。这些方法用于估计新像素位置的像素值,以确保图像的平滑过渡和减少失真。

(1)最近邻插值(Nearest Neighbor Interpolation):

  • 原理:选择最接近的新像素位置的原始像素值。
  • 优点:简单、速度快。
  • 缺点:图像可能会有锯齿状边缘和块状效果,特别是在放大图像时。

(2)双线性插值(Bilinear Interpolation):

  • 原理:通过在两个方向上(水平和垂直)进行线性插值来计算新像素值。
  • 优点:比最近邻插值更平滑,减少了锯齿状边缘。
  • 缺点:计算量比最近邻插值大,但仍然比更高级的插值方法快。

(3)双三次插值(Bicubic Interpolation):

  • 原理:使用16个相邻像素点,通过三次多项式计算新像素值。
  • 优点:可以得到非常平滑的图像,质量较高。
  • 缺点:计算量较大,速度较慢。

(4)三次样条插值(Cubic Spline Interpolation):

  • 原理:使用三次样条函数来插值,通常用于需要平滑数据的场景。
  • 优点:可以得到非常平滑的图像,边缘清晰。
  • 缺点:计算复杂,速度慢。

(5)Lanczos插值:

  • 原理:使用称为Lanczos窗口的正弦函数的变体来计算插值,可以看作是加权的 sinc 函数。
  • 优点:在保持图像细节方面非常有效,质量高。
  • 缺点:计算量最大,速度慢。

(6)区域插值(Area Interpolation):

  • 原理:根据原始图像中对应于新像素位置的区域来计算像素值。
  • 优点:在缩小图像时特别有用,可以避免混叠效应。
  • 缺点:计算量较大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值