OpenCV学习(4.2) 图像的几何变换

1.目标

  • 学习将不同的几何变换应用到图像上,如平移、旋转、仿射变换等。
  • 你会看到这些函数: cv.getPerspectiveTransform

2.缩放

缩放是调整图片的大小。 OpenCV 使用 cv.resize() 函数进行调整。可以手动指定图像的大小,也可以指定比例因子。可以使用不同的插值方法。对于下采样(图像上缩小),最合适的插值方法是 cv.INTER_AREA 对于上采样(放大),最好的方法是 cv.INTER_CUBIC (速度较慢)和 cv.INTER_LINEAR (速度较快)。默认情况下,所使用的插值方法都是 cv.INTER_AREA 。你可以使用如下方法调整输入图片大小:

代码:

import cv2



image = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
image = cv2.imread(image)



#图像几何变换
import numpy as np


res11 = cv2.resize(image,None,fx=2, fy=2, interpolation = cv2.INTER_AREA)
res12 = cv2.resize(image,None,fx=2, fy=2, interpolation = cv2.INTER_LINEAR)
res13 = cv2.resize(image,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)
#OR
height, width = image.shape[:2]
res2 = cv2.resize(image,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

cv2.imshow('res11',res11)
cv2.imshow('res12',res12)
cv2.imshow('res13',res13)
cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在OpenCV中,cv2.resize() 函数用于改变图像的大小。您提供的代码行演示了如何将输入图像 image 放大到原来的两倍。

这里是代码行的详细解释:

  • res11 = cv2.resize(image, None, fx=2, fy=2, interpolation = cv2.INTER_AREA):这行代码执行了图像放大的操作。
    • image 是您想要调整大小的图像。
    • None 表示输出图像的大小会根据 fx 和 fy 参数自动计算。如果您想显式指定输出图像的大小,可以传递一个元组 (width, height)
    • fx=2 和 fy=2 表示图像在 x 轴和 y 轴方向上放大两倍。
    • interpolation=cv2.INTER_AREA 是插值方法,用于在放大或缩小图像时确定新像素值。cv2.INTER_AREA 是一种适合缩小图像的插值方法,但如果您是在放大图像,通常使用 cv2.INTER_LINEAR 或 cv2.INTER_CUBIC 会得到更好的结果,因为它们可以提供更平滑的边缘和更少的锯齿效果。

如果您的目的是放大图像,通常建议使用 cv2.INTER_LINEAR 或 cv2.INTER_CUBIC 作为插值方法。

 

输出结果: 

3.平移变换

平移变换是物体位置的移动。如果知道 (x,y) 方向的偏移量,假设为 (t_x,t_y)**,则可以创建如下转换矩阵 **M

您可以将变换矩阵存为 np.float32 类型的 numpy 数组,并将其作为 cv.warpAffine 的第二个参数。请参见以下转换(100,50)的示例:

import numpy as np
import cv2 as cv


img = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
img = cv.imread(img)
cv.imshow('img',img)
print(img.shape)
rows,cols = img.shape[0],img.shape[1]
M1 = np.float32([[1,0,100],[0,1,50]])
M2 = np.float32([[1,0,50],[0,1,100]])
M3 = np.float32([[1,0,-100],[0,1,-50]])
M4 = np.float32([[1,0,-50],[0,1,-100]])
dst1 = cv.warpAffine(img,M1,(cols,rows))
dst2 = cv.warpAffine(img,M2,(cols,rows))
dst3 = cv.warpAffine(img,M3,(cols,rows))
dst4 = cv.warpAffine(img,M4,(cols,rows))
cv.imshow('img1',dst1)
cv.imshow('img2',dst2)
cv.imshow('img3',dst3)
cv.imshow('img4',dst4)
cv.waitKey(0)
cv.destroyAllWindows()

dst1 = cv.warpAffine(img,M1,(cols,rows))

在OpenCV中,cv.warpAffine() 函数用于对图像进行仿射变换。这个函数可以将图像按照给定的变换矩阵进行旋转、平移、缩放等变换。

以下是代码行的详细解释:

  • dst1 = cv.warpAffine(img, M1, (cols, rows))
    • img 是您想要进行仿射变换的输入图像。
    • M1 是一个2x3的变换矩阵,它定义了如何变换图像。这个矩阵通常是通过计算得到的,它包含了图像的旋转、平移和缩放信息。
    • (cols, rows) 是输出图像的大小,cols 是输出图像的列数,rows 是输出图像的行数。这个参数确定了变换后图像的大小。

例如,如果您想要将图像绕其中心旋转30度,您可以首先计算旋转矩阵 M1,然后使用 cv.warpAffine() 函数进行变换

 

cv.warpAffine 函数的第三个参数是输出图像的大小,其形式应为(宽度、高度)。记住宽度=列数,高度=行数。 

输入:

输出:

4.旋转 

以 \theta角度旋转图片的转换矩阵形式为:

但 Opencv 提供了可变旋转中心的比例变换,所以你可以在任意位置旋转图片,修改后的转换矩阵为:

其中:

为了找到这个转换矩阵,opencv 提供了一个函数, cv.getRotationMatrix2D 。请查看下面的示例,它将图像相对于中心旋转 90 度,而不进行任何缩放。

import cv2 as cv


img = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
img = cv.imread(img)
cv.imshow('img',img)

rows,cols = img.shape[0],img.shape[1]
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('dst',dst)

cv.waitKey(0)
cv.destroyAllWindows()

cv.getRotationMatrix2D 是 OpenCV 库中的一个函数,用于计算二维旋转的变换矩阵。这个变换矩阵可以随后用于 cv.warpAffine 函数中,以实现对图像的旋转。

函数原型如下:

cv.getRotationMatrix2D(center, angle, scale)

参数说明:

  • center:旋转的中心点,通常是一个二元组 (x, y),表示图像中的旋转中心。
  • angle:旋转角度,正值表示逆时针旋转。
  • scale:缩放因子,用于在旋转的同时对图像进行缩放。

返回值是一个 2x3 的浮点型 NumPy 数组,表示旋转变换矩阵。

 

5.仿射变换

仿射变换是一种二维变换,它在平面内将一个图形变换成另一个图形,同时保持原图形中所有点之间的相对位置关系(即直线经过变换后仍然是直线,且平行线经过变换后仍然平行)。在仿射变换中,直线段保持直线且比例不变,但直线段可能会变短或变长。

仿射变换可以由以下几种基本变换组合而成:

  1. 平移(Translation):在平面上沿着某个方向移动所有点。
  2. 旋转(Rotation):围绕某个点旋转所有点。
  3. 缩放(Scaling):放大或缩小所有点,可以有不同的缩放比例沿 x 轴和 y 轴。
  4. 剪切(Shear):使平面上的点沿某个方向移动,移动的距离与点到某条参考线的距离成正比。

在数学上,仿射变换通常表示为一个矩阵和一个向量的组合,形式如下:

                                                               T(x)=Ax+b

其中,A 是一个 2x2 的矩阵,表示旋转、缩放和剪切,b 是一个 2 元素的向量,表示平移,x 是原始点的坐标,T(x) 是变换后点的坐标。

在图像处理中,仿射变换常用于校正图像的视角、校正由于相机镜头造成的畸变、或者将图像中的对象进行几何变换。在 OpenCV 中,可以使用 cv.getAffineTransform 来计算仿射变换矩阵,然后使用 cv.warpAffine 来应用这个变换到图像上。

在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要从输入图像中取三个点及其在输出图像中的对应位置。然后 cv.getAffineTransform 将创建一个 2x3 矩阵,该矩阵将传递给 cv.warpAffine 。

查看下面的示例,并注意我选择的点(用绿色标记):

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

img = r'D:\study\EmotionDetection_RealTime-master\data\data\te\03.jpg'
img = cv.imread(img)
cv.imshow('img',img)


rows,cols = img.shape[0],img.shape[1]
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

cv.waitKey(0)
cv.destroyAllWindows()

6.透视变换 

透视变换(Perspective Transformation)是一种更加一般的变换,它可以将一个平面上的图像映射到另一个平面上,同时保持直线的直线性质,但不保持平行线的平行性。这意味着,透视变换可以改变物体的视角,使得原本平行的线在变换后的图像中会相交,产生一种深度感或透视效果

透视变换在图像处理中的应用非常广泛,比如在图像校正、三维重建、虚拟现实和增强现实等领域。它允许我们从一个特定的视角观察一个物体,就像我们通过窗户看外面的世界,窗户的框架会提供一个不同的视角,即使窗户外的物体是平面的。

在数学上,透视变换通常通过一个3x3的变换矩阵来表示,这个矩阵可以将一个二维坐标系中的点映射到另一个二维坐标系中的点。透视变换矩阵的构造通常需要四个对应的点对,即原始图像中的四个点及其在目标图像中的对应位置。

在OpenCV中,可以使用cv.getPerspectiveTransform函数来计算透视变换矩阵,然后使用cv.warpPerspective函数来应用这个变换到图像上

对透视转换,你需要一个 3x3 变换矩阵。即使在转换之后,直线也将保持直线。要找到这个变换矩阵,需要输入图像上的 4 个点和输出图像上的相应点。在这四点中,任意三点不应该共线。然后通过 cv.getPerspectiveTransform 找到变换矩阵。然后对这个 3x3 变换矩阵使用 **cv.warpPerspective**。

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

img = r'D:\study\EmotionDetection_RealTime-master\data\data\te\01.jpg'
img = cv.imread(img)
cv.imshow('img',img)


rows,cols = img.shape[0],img.shape[1]
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(rows,cols))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

cv.waitKey(0)
cv.destroyAllWindows()


cv.getPerspectiveTransform 是 OpenCV 库中的一个函数,用于计算透视变换矩阵。透视变换是一种投影变换,它可以将一个平面上的图像映射到另一个平面上,同时保持直线的直线性质,但不保持平行线的平行性。这种变换通常用于校正图像中的透视畸变,例如将照片中的矩形对象(如建筑物的立面)转换为正视图像。

函数原型如下:

cv.getPerspectiveTransform(src, dst)

参数说明:

  • src:一个包含四个源点的 numpy 数组,这些点代表原始图像中的四个角点。
  • dst:一个包含四个目标点的 numpy 数组,这些点代表变换后图像中对应角点的期望位置。

返回值是一个 3x3 的浮点型 NumPy 数组,表示透视变换矩阵。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值