OpenCV库的学习笔记(四)Geometric Transformations of Images

目标

  • 学习对图像应用不同的几何变换,如平移、旋转、仿射变换等;
  • 你会看到这些功能: cv.getPerspectiveTransform

转换

OpenCV 提供了两个转换函数,cv.warpAffinecv.warpPerspective,您可以使用它们执行各种转换。 cv.warpAffine 采用 2x3 变换矩阵,而 cv.warpPerspective 采用 3x3 变换矩阵作为输入。

缩放

缩放只是调整图像的大小。为此,OpenCV 带有一个函数 cv.resize()。可以手动指定图像的大小,也可以指定比例因子。使用不同的插值方法。首选的插值方法是用于缩小的 cv.INTER_AREA 和用于放大的 cv.INTER_CUBIC(慢)cv.INTER_LINEAR。默认情况下,插值方法 cv.INTER_LINEAR 用于所有调整大小的目的。您可以使用以下任一方法调整输入图像的大小:

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)
#像素放大为原来长宽的两倍

平移

平移是物体位置的移动。如果您知道 (x,y) 方向的偏移并让它成为 (tx,ty),您可以创建变换矩阵 M,如下所示:

M=\begin{bmatrix} 1 & 0 &t_x \\ 0 & 1 &t_y \end{bmatrix}

您可以将其放入 np.float32 类型的 Numpy 数组中,并将其传递给 cv.warpAffine() 函数。有关 (100,50) 的移位,请参见以下示例:

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()
#这里我的理解是tx是x轴移动距离,ty是y轴移动距离

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

 旋转

图像旋转角度 θ 是通过以下形式的变换矩阵实现的:

M=\begin{bmatrix} cos\theta & -sin\theta\\ sin\theta & cos\theta \end{bmatrix}

但是 OpenCV 提供了旋转中心可调的缩放旋转,这样你就可以在任何你喜欢的位置旋转。修改后的变换矩阵由下式给出:

\begin{bmatrix} \alpha &\beta &(1-\alpha)\cdot center.x-\beta \cdot center.y \\ -\beta& \alpha & \beta \cdot center.x+(1-\alpha)\cdot center.y \end{bmatrix}

其中

\alpha =scale\cdot cos\theta \\ \beta =scale\cdot sin\theta

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

img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
# 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.getAffineTransform 将创建一个 2x3 矩阵,该矩阵将传递给 cv.warpAffine

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

OpenCV库的学习笔记(四)Geometric Transformations of Images_第1张图片

img = cv.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
#点坐标1
pts2 = np.float32([[10,100],[200,50],[100,250]])
#点坐标2
M = cv.getAffineTransform(pts1,pts2)
#参数1:原始图像中三个点的坐标 参数2:变换后三个点的坐标, M 是根据三个对应点求出的仿射变换矩阵
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()

透视变换

对于透视变换,您需要一个 3x3 变换矩阵。即使在转换之后,直线仍将保持笔直。要找到这个变换矩阵,您需要输入图像上的 4 个点和输出图像上的对应点。这4个点中,有3个不应该共线。然后可以通过函数 cv.getPerspectiveTransform 找到变换矩阵。然后将 cv.warpPerspective 与这个 3x3 变换矩阵一起应用。

img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
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)
#这个和上面一样不过要求是4个点
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')

 

OpenCV库的学习笔记(四)Geometric Transformations of Images_第2张图片

 

你可能感兴趣的:(opencv,学习,计算机视觉)