6.openCV调整图像大小新思路(cv2.resize和imutils.resize)

12 篇文章 0 订阅
8 篇文章 1 订阅

在本教程中,您将学习如何使用 OpenCV 和 cv2.resize 功能。

缩放或简单地调整大小是在宽度和高度方面增加或减小图像大小的过程。

调整图像大小时,重要的是要记住纵横比- 即图像的宽度与其高度的比率。忽略纵横比可能会导致调整大小的图像看起来压缩和扭曲:

在左边,我们有我们的原始图像。在右侧,我们有两张因不保留纵横比而失真的图像。它们已通过忽略图像的宽度与高度的比率来调整大小。

图1

通常,您需要在调整大小时保留图像的纵横比——尤其是当这些图像作为输出呈现给用户时。不过,例外情况肯定适用。当我们探索机器学习/深度学习技术时,我们会发现我们的内部算法经常忽略图像的纵横比;但是一旦我们了解了计算机视觉的基础知识,就会有更多的了解。

我们还需要记住调整大小函数的插值方法。插值的正式定义是:

在一组离散的已知数据点的范围内构建新数据点的方法。

  • 插值
    在这种情况下,“已知点”是我们原始图像的像素。插值函数的目标是获取这些像素邻域并使用它们来增加或减少图像的大小。

一般来说,减小图像的大小会更有益(并且在视觉上更吸引人)。这是因为插值函数只需从图像中删除像素。另一方面,如果我们要增加图像的尺寸,插值函数就必须“填补”以前不存在的像素之间的空隙。

例如,看一下下图中的图像:在这里插入图片描述
在左边,我们有我们的原始图像。在中间,我们将图像大小调整为原来的一半——除了图像被调整大小之外,图像“质量”没有任何损失。但是,在右侧,我们显着增加了图像大小。它现在看起来“像素化”。

正如我上面提到的,您通常会减小图像的大小而不是增加(当然,例外情况确实适用)。通过减小图像尺寸,我们可以处理更少的像素(更不用说处理的“噪音”更少),这导致更快、更准确的图像处理算法。

请记住,虽然高分辨率图像在视觉上对人眼有吸引力,但它们会损害计算机视觉和图像处理管道:

  • 根据定义,图像越大,数据越多,因此算法处理数据所需的时间越长
  • 高分辨率图像非常详细——但从计算机视觉/图像处理的角度来看,我们更感兴趣的是图像的结构成分,而不是超细粒度的细节
  • 大分辨率图像几乎总是被下采样,以帮助图像处理系统运行得更快、更准确

一、openCV 调整图像大小 ( cv2.resize )

在本教程的第一部分中,我们将配置我们的开发环境并查看我们的项目目录结构。

  • 使用 OpenCV 调整图像大小的基础知识和 cv2.resize (不知道长宽比)
  • 如何使用调整尺寸 imutils.rotate (知道纵横比)
  • 您可以使用 OpenCV 中的插值方法(当您需要对图像进行下采样或上采样时很有用)

二、项目结构和代码讲解

1.项目结构

通过博文末尾或此处的的代码:下载.
下载本博文对应的代码项目,以下是下载解压后的项目结构:
在这里插入图片描述
我们的 opencv_resize.py 文件将加载输入 .png 图像,然后执行几个调整大小的操作,从而演示如何使用 OpenCV 的 cv2.resize 调整图像尺寸的功能。

使用 OpenCV 实现基本的图像大小调整
到目前为止,在本相关博文中,我已经介绍了两种图像变换:平移和旋转。现在,我们将探讨如何调整图像大小。

也许,毫不奇怪,我们使用 cv2.resize功能来调整我们的图像。正如我上面提到的,我们在使用这个函数时需要记住图像的纵横比。

2.代码讲解

在这里插入图片描述
我们从第 2-4 行开始并导入所需的 Python 包。

第 7-10 行解析我们的命令行参数。我们只需要一个参数,- image,即我们要调整大小的输入图像的路径。

现在让我们从磁盘加载这个图像:在这里插入图片描述
第 13 和 14 行加载我们的输入图像 从磁盘并将其显示在我们的屏幕上:在这里插入图片描述
调整图像大小时,我们需要记住图像的纵横比。纵横比是图像的宽度和高度的比例关系:

纵横比 = 图像宽度 / 图像高度
如果我们不注意纵横比,我们调整大小将返回看起来失真的结果。

计算调整大小的比率在第 19 行处理。在这行代码中,我们将新的图像宽度定义为150像素。要计算新高度与旧高度的比例,我们只需定义我们的比例r 是新宽度(150 像素)除以旧宽度,我们使用 image.shape [ 1 ].

现在我们有了比例,我们可以在第 20 行计算图像的新尺寸。同样,新图像的宽度将为 150 像素。然后通过将旧高度乘以我们的比率并将其转换为整数来计算高度。通过执行此操作,我们保留了图像的原始纵横比。

图像的实际调整发生在第 23 行。第一个参数是我们希望调整大小的图像,第二个参数是我们为新图像计算的尺寸。最后一个参数是我们的插值方法,它是在幕后处理我们如何调整实际图像大小的算法。

最后,我们在第 24 行显示调整后的图像:在这里插入图片描述
在我们探索的示例中,我们仅通过指定宽度来调整图像的大小。但是如果我们想通过设置高度来调整图像大小呢?所需要的只是更改用于保持纵横比的调整大小比率的计算:在这里插入图片描述
在第 28 行,我们重新定义我们的比率,r. 我们的新图像的高度为 50 像素。为了确定新高度与旧高度的比率,我们将 50 除以旧高度。

然后,我们定义新图像的尺寸。我们已经知道新图像的高度为 50 像素。新宽度是通过将旧宽度乘以比率获得的,使我们能够保持图像的原始纵横比。

然后我们在第 32 行执行图像的实际调整大小并在第 33行显示它:在这里插入图片描述
在这里,我们可以看到我们在保持纵横比的同时,在宽度和高度方面都调整了原始图像的大小。如果我们不保留纵横比,我们的图像看起来会失真。

调整图像大小很简单,但必须计算纵横比,定义新图像的尺寸,然后执行调整大小需要三行代码。这三行代码虽然看起来并不多,但可以使我们的代码变得非常冗长和混乱。

相反,我们可以使用 imutils.resize 功能,可自动为我们处理计算和维护宽高比:在这里插入图片描述
在此示例中,您可以看到单个函数处理图像大小调整: imutils.resize.

我们传入的第一个参数是 图像我们想调整大小。然后,我们指定关键字参数宽度,这是我们新图像的目标宽度。然后该函数为我们处理调整大小:在这里插入图片描述
当然,我们也可以通过将函数调用更改为:在这里插入图片描述
在这里插入图片描述
请注意,我们的输出调整大小的图像现在明显小于原始图像,但纵横比仍然保持不变。

3.比较 OpenCV 插值方法

到目前为止,我们只使用了 cv2.INTER_AREA插值方法。正如我在本文开头提到的,插值函数的目标是检查像素的邻域并使用这些邻域在不引入失真(或至少尽可能少的失真)的情况下以光学方式增加或减小图像的大小。

第一种方法是最近邻插值,由 cv2.INTER_NEAREST 。这种方法是最简单的插值方法。这种方法不是计算相邻像素的加权平均值或应用复杂的规则,而是简单地找到“最近”的相邻像素并假设强度值。尽管此方法既快速又简单,但调整大小后的图像质量往往相对较差,并可能导致“块状”伪像。

其次,我们有 cv2.INTER_LINEAR方法,它执行双线性插值——这是 OpenCV 在调整图像大小时默认使用的方法。双线性插值背后的一般思想可以在任何小学数学教科书中找到——斜率截距形式:

y = mx + b

显然,我概括了很多。尽管如此,我们要做的不仅仅是找到“最近的”像素并假设它的值(如最近邻插值)。我们现在取相邻像素并使用该邻域来计算插值(而不是仅假设最近的像素值)。

第三,我们有 cv2.INTER_AREA插值法。对该方法的工作原理进行全面审查超出了本教程的范围。不过,我建议您阅读这篇文章,它提供了此方法的一般系数规则的高级概述。

最后,我们有 cv2.INTER_CUBIC 和 cv2.INTER_LANCZOS4.

这些方法速度较慢(因为它们不再使用简单的线性插值,而是使用样条)并在方形像素邻域上使用双三次插值。

这 cv2.INTER_CUBIC该方法在4 x 4像素的邻居上运行,并且cv2.INTER_LANCZOS4超过8 x 8像素的邻域。一般来说,我很少看到cv2.INTER_LANCZOS4 实践中使用的方法。

既然我们已经讨论了 OpenCV 提供的插值方法,让我们编写一些代码来测试它们:

在这里插入图片描述
我们首先在第45-50行定义插值方法列表。

从那里开始,我们遍历每种插值方法,并在第57和58行上调整图像的大小(向上采样,使其比原始图像大3倍)。

然后调整大小的结果显示在我们的屏幕上的第 60 行。

我们来看看最近邻插值的输出:在这里插入图片描述
块状工件又回来了。据我所知,cv2.INTER_AREA 表现非常相似 cv2.INTER_NEAREST.

然后我们继续进行双三次插值在这里插入图片描述
双三次插值进一步消除了块状伪影。

最后, cv2.LANCOSZ4 方法,这似乎与双三次方法非常相似:在这里插入图片描述

4.OpenCV 图像大小调整结果

要使用 OpenCV 调整图像大小,请务必访问本教程的“下载”部分以检索源代码和示例图像。

我们已经审查了我们的结果 opencv_resize.py 脚本,但如果您想通过终端执行此脚本,只需使用以下命令:在这里插入图片描述

三、代码下载

下载.

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
OpenCV中的resize函数和PyTorch中的F.interpolate函数都可以用来调整图像大小,但它们的使用方法和结果略有不同。 1. resize函数 resize函数可以直接调整图像大小,并且可以选择不同的插值方法来处理图像的像素值。常用的插值方法有:INTER_NEAREST、INTER_LINEAR、INTER_CUBIC和INTER_LANCZOS4。 使用resize函数时,需要指定输出图像大小和插值方法,例如: ```python import cv2 img = cv2.imread('image.jpg') resized_img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_LINEAR) ``` 2. F.interpolate函数 F.interpolate函数是PyTorch中针对张量的插值函数,可以用于调整图像大小。与resize函数不同的是,F.interpolate函数需要将图像转换成PyTorch的张量,然后再进行插值操作。 使用F.interpolate函数时,需要指定输出张量的大小和插值方法,例如: ```python import torch import torch.nn.functional as F img = cv2.imread('image.jpg') tensor_img = torch.from_numpy(img).permute(2, 0, 1).unsqueeze(0).float() resized_tensor_img = F.interpolate(tensor_img, size=(new_height, new_width), mode='bilinear', align_corners=True) resized_img = resized_tensor_img.squeeze().permute(1, 2, 0).numpy().astype('uint8') ``` 3. 区别 resize函数和F.interpolate函数的区别在于: - resize函数可以直接操作图像,而F.interpolate需要将图像转换成张量后再操作。 - resize函数可以选择不同的插值方法,而F.interpolate只能选择双线性插值或最近邻插值。 - F.interpolate函数可以在GPU上进行加速,而resize函数只能在CPU上运行。 因此,如果只需要调整图像大小,可以使用resize函数;如果需要在PyTorch中进行深度学习,可以使用F.interpolate函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

·菜鸟看世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值