这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。
如果有喜欢我笔记的请麻烦帮我关注、点赞、评论。谢谢诸位。
学习笔记:
学习笔记目录里面会收录我关于OpenCV系列学习笔记博文,大家如果有什么不懂的可以通过阅读我的学习笔记进行学习。
【OpenCV学习笔记】- 学习笔记目录
内容
- 你将会学到将不同的几何变换应用于图像,如平移、旋转、仿射变换等。
- 你会学到如下函数:cv.getPerspectiveTransform
变换
OpenCV 提供了两个转换函数,cv2.warpAffine 和 cv2.warpPerspective,可以进行各种转换。 cv.warpAffine 采用 2x3 变换矩阵,而 cv.warpPerspective 采用 3x3 变换矩阵作为输入。
缩放
缩放是调整图片的大小。 OpenCV 使用 cv2.resize() 函数进行调整。可以手动指定图像的大小,也可以指定比例因子。可以使用不同的插值方法。对于下采样(图像上缩小),最合适的插值方法是 cv2.INTER_AREA 对于上采样(放大),最好的方法是 cv2.INTER_CUBIC (速度较慢)和 cv2.INTER_LINEAR (速度较快)。默认情况下,所使用的插值方法都是 cv2.INTER_AREA 。你可以使用如下方法调整输入图片大小。
示例代码:
# 图像的几何变换
# 缩放
import numpy as np
import cv2
img = cv2.imread('../image/1.jpg')
cv2.imshow("img", img)
res1 = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
cv2.imshow("res1", res1)
# OR
height, width = img.shape[:2]
res2 = cv2.resize(img, (2 * width, 2 * height), interpolation=cv2.INTER_CUBIC)
cv2.imshow("res2", res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
平移变换
平移变换是物体位置的移动。如果知道 (x,y) 方向的偏移量,假设为 (t_x,t_y),则可以创建如下转换矩阵 M:
您可以将变换矩阵存为 np.float32 类型的 numpy 数组,并将其作为 cv.warpAffine 的第二个参数。请参见以下转换(100,50)的示例:
示例代码:
# 图像的几何变换
# 平移变换
import numpy as np
import cv2
img = cv2.imread('../image/3.1-test.jpg', 0)
cv2.imshow('img', img)
rows, cols = img.shape
M = np.float32([[1, 0, 100], [0, 1, 50]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:cv.warpAffine 函数的第三个参数是输出图像的大小,其形式应为(宽度、高度)。记住宽度=列数,高度=行数。
效果图:
旋转
以 角度旋转图片的转换矩阵形式为:
但 Opencv 提供了可变旋转中心的比例变换,所以你可以在任意位置旋转图片,修改后的转换矩阵为:
其中:
为了找到这个转换矩阵,opencv 提供了一个函数, cv.getRotationMatrix2D 。请查看下面的示例,它将图像相对于中心旋转 90 度,而不进行任何缩放。
示例代码:
# 图像的几何变换
# 旋转
import cv2
img = cv2.imread('../image/3.1-test.jpg', 0)
cv2.imshow('img', img)
rows, cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv2.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), 90, 1)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果图:
仿射变换
在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要从输入图像中取三个点及其在输出图像中的对应位置。然后 cv2.getAffineTransform 将创建一个 2x3 矩阵,该矩阵将传递给 cv2.warpAffine 。
查看下面的示例,并注意我选择的点(用绿色标记):
示例代码:
# 图像的几何变换
# 仿射变换
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('../image/3.2.png')
rows, cols, ch = img.shape
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.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 个点和输出图像上的相应点。在这四点中,任意三点不应该共线。然后通过 cv2.getPerspectiveTransform 找到变换矩阵。然后对这个 3x3 变换矩阵使用 cv2.warpPerspective。
示例代码:
# 图像的几何变换
# 透视变换
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('../image/3.2.2.png')
rows, cols, ch = img.shape
pts1 = np.float32([[47, 52], [305, 42], [22, 319], [321, 321]])
pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (300, 300))
plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()
原图:
效果图:
彩蛋
对图片内容进行矫正
官网推荐的书
“Computer Vision: Algorithms and Applications”(计算机视觉:算法和应用), Richard Szelisk