opencv和imutils图像旋转新方案
在本教程中,您将学习如何使用 OpenCV 旋转图像。此外,我还将向您展示如何使用 imutils 库中的两个便捷函数旋转图像,imutils.rotate 和 imutils.rotate_bound,这使得使用 OpenCV 旋转图像更容易(并且需要更少的代码)。
之前,我们学习了如何平移(即平移)图像,向上、向下、向左和向右(或任意组合)。我们现在进入下一个图像处理主题——旋转。
旋转正好听起来像:将图像旋转某个角度\大\θ。我们将使用\大\θ来表示我们旋转图像的度数(不是弧度)。
我还将向您展示一些使 OpenCV 旋转图像更容易的技术
一、openCV 旋转图像
在本教程的第一部分,我们将讨论 OpenCV 如何旋转图像以及可用于旋转的函数。
从那里,我们将配置我们的开发环境并检查我们的项目目录结构。
然后,我将向您展示使用 OpenCV 旋转图像的三种方法:
使用 cv2.rotate功能:内置于OpenCV中,但需要构建旋转矩阵并显式复制变形,使代码更加冗长。
使用 imutils.rotate功能:我的imutils库的部分。可以在单个函数调用中使用OpenCV旋转图像。
使用 imutils.rotate_bound功能:也是我的库的一部分。确保在旋转过程中不会切断图像的任何部分。
openCV 如何旋转图像?
与translation类似,或许不出所料,θ可以通过构造矩阵M来定义角度旋转,其形式为:
给定一个(x, y) -笛卡尔平面,该矩阵可用于围绕θ原点旋转的旋转数(逆时针)。在这种情况下,原点通常是图像的中心;然而,在实践中,我们可以定义任意的(x, y)坐标作为我们的旋转中心。
从原始图像I,旋转图像R然后通过简单矩阵乘法获得:R = I * M
然而,OpenCV 还提供了 (1) 缩放(即调整大小)图像和 (2) 提供任意旋转中心以执行旋转的能力。
因此,我们修改后的旋转矩阵M为:
其中
和
和cx和cy是相应的(x, y)坐标,围绕该坐标执行旋转。
开发环境需要opencv和imutils
其中opencv自行解决,
imutils通过
pip install imutils
二、项目结构和代码讲解
请务必访问本教程最后的“链接: 下载源码.”部分以检索源代码和示例图像,然后从那里查看内部信息:
在这里,我们有 opencv_rotate.py. 此脚本将加载opencv_logo.png (或您选择的任何其他图像),然后对其应用一系列旋转,从而演示如何使用 OpenCV 执行旋转。
代码讲解
打开 opencv_rotate.py 项目目录结构中的文件并插入以下代码
第 2-4 行导入我们需要的 Python 包。我们会用argparse对于命令行参数,imutils用于我的 OpenCV 便利函数集(即imutils.rotate 和 imutils.rotate_bound 方法),以及 简历2 对于我们的 OpenCV 绑定。
我们只有一个命令行参数, - 图像,这是我们想要旋转的输入图像的路径(我们默认为 opencv_logo.png).
我们首先加载我们的输入图像并将其显示在我们的屏幕上:
旋转图像时,需要指定要旋转的点。在大多数情况下,您会希望围绕图像的中心旋转;但是,OpenCV 允许您指定要旋转的任意点(如上所述)。
让我们继续并围绕图像的中心旋转。第18和19行抓取图像的宽度和高度,然后将每个分量除以2 来确定图像的中心。
正如我们定义一个矩阵来平移图像一样,我们也定义了一个矩阵来旋转图像。而不是使用 NumPy 手动构建矩阵(这可能有点乏味),我们只需调用cv2.getRotationMatrix2D第 22 行的方法。
这 cv2.getRotationMatrix2D函数接受三个参数。第一个参数是我们旋转图像的点(在这种情况下,中心CX 和 Y 图像)。
然后我们指定θ,我们将旋转图像的(逆时针)度数。在这种情况下,我们将图像旋转 45 度。
最后一个参数是图像的比例。我们还没有讨论调整图像大小,但在这里您可以指定一个浮点值,其中1.0表示使用相同的图像原始尺寸。但是,如果您指定的值为2.0,则图像大小会加倍 — 类似地,值0.5会将图像大小减半。
一旦我们M从cv2.getRotationMatrix2D 功能,我们可以使用旋转应用到我们的图像 cv2.warp仿射第 23 行的方法。
这个函数的第一个参数是 图像我们想旋转。然后,我们指定旋转矩阵米以及我们图像的输出尺寸(宽度和高度)。然后第 24 行显示了我们旋转 45 度的图像:
第 27-29 行做同样的事情,但这次旋转图像-90 围绕中心度数(顺时针) CX 和 Y 坐标。
注意:请记住,在 OpenCV 中,正度数表示逆时针旋转,而负度数表示顺时针旋转。记住这一点;否则,在对自己的图像应用旋转时可能会感到困惑!
图 4显示了这些调整大小操作的输出:
如您所见,我们的图像已旋转。请注意,OpenCV不会自动为我们整个旋转的图像分配空间以适应框架。
这是预期的行为!如果您希望旋转后整个图像适合视图,则需要修改宽度和高度,表示为( w, h ) 在里面 cv2.warp仿射功能。正如我们稍后将在此脚本中看到的那样,imutils.rotate_bound 函数为我们处理所有这些。
到目前为止,我们只围绕图像中心旋转了图像。但是如果我们想围绕某个任意点旋转图像怎么办?
让我们继续,看看这是如何实现的:
到现在为止,这段代码对于执行旋转来说应该是相当标准的。但是,请注意第一个参数cv2.getRotationMatrix2D功能。在这里,我们表明,我们要旋转的图像周围X = 10,Y = 10,或大约左上角的图像角。
当我们应用此旋转时,我们的输出图像如下所示
我们可以看到旋转的中心不再是图像的中心。
但是,就像翻译图像一样,调用两者 cv2.getRotationMatrix2D 和 cv2.warp仿射 可能会变得非常乏味——更不用说它也会使我们的代码变得更加冗长。
让我们通过调用减少我们需要编写的代码量 imutils.rotate,一种方便的功能,用于包装对的调用 cv2.getRotationMatrix2D 和 cv2.warp仿射:
在这里,我们将图像旋转了 180 度,但是我们可以通过使用 旋转 方法。
图 6显示了我们旋转的输出
正如您在前面的示例中看到的那样,如果在旋转过程中部分图像被切掉,OpenCV 不会分配足够的空间来存储整个图像。
解决方法是使用 imutils.rotate_bound 功能:
此函数将自动扩展图像阵列,使整个旋转图像适合其中。
应用结果 旋转边界函数可以在图 7 中看到,我们将图像逆时针旋转 33 度:
注:该imutils.rotate_bound函数反转正/负值和顺时针/逆时针旋转之间的关系。在这里,负值将逆时针旋转,而正值将顺时针旋转。
使用 OpenCV 应用图像旋转时,您有三个选项:
- cv2.getRotationMatrix2D 和 cv2.warp仿射
- imutils.rotate
- imutils.rotate_bound
根据您认为适合您自己的应用程序来混合和匹配它们。
三、代码获取
链接: 下载源码.