OpenCV resize:掌握图片尺寸调整与插值方法 – wiki基地


OpenCV resize:掌握图片尺寸调整与插值方法——从理论到实践的深度解析

在计算机视觉和图像处理领域,图片尺寸的调整是一项基础且至关重要的操作。无论是为了适应不同的显示设备、准备机器学习模型的输入、生成缩略图,还是进行各种图像分析预处理,resize 函数都扮演着核心角色。OpenCV作为功能强大的开源计算机视觉库,提供了高效且灵活的 cv2.resize 函数,让我们能够精确地控制图像的尺寸调整过程。

本文将带领您深入探索OpenCV中的 resize 函数,从其基本用法、参数解析,到核心的插值方法理论与实践,以及在不同场景下的选择策略,最终结合实际代码示例,帮助您彻底掌握这项技能。

第一章:初识 cv2.resize——图片尺寸调整的基石

1.1 resize 函数的地位与重要性

图像尺寸调整,顾名思义,就是改变图像的宽度和高度。这项操作在日常开发中无处不在:
* 适配用户界面:将图片调整到合适的尺寸以在网页、移动应用或桌面软件中显示。
* 深度学习预处理:卷积神经网络(CNN)通常要求输入图片具有固定的尺寸(如224×224、300×300等),resize 是将各种尺寸的原始图像统一化的关键步骤。
* 节省存储和传输带宽:生成图片的缩略图(thumbnails)可以大大减少存储空间和网络传输的开销。
* 加速处理速度:在某些图像分析任务中,对较小的图像进行操作可以显著提高处理效率。
* 多尺度分析:在一些计算机视觉算法中,可能需要在不同尺寸的图像上进行特征提取或目标检测。

1.2 cv2.resize 函数的基本语法

OpenCV Python binding中 resize 函数的基本语法如下:

python
dst = cv2.resize(src, dsize, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)

参数解释:

  • src:输入图像。这是一个NumPy数组,通常是彩色图像(BGR三通道)或灰度图像(单通道)。
  • dsize:输出图像的尺寸。这是一个元组 (width, height)。请注意,OpenCV中的尺寸表示通常是 (宽度, 高度),而不是NumPy数组形状的 (高度, 宽度),这在初学者中经常引起混淆。
    • 如果 dsize(0, 0),则通过 fxfy 参数进行缩放。
  • fx:沿水平方向(宽度)的缩放因子。
    • 如果 dsize 不为 (0, 0),则此参数不起作用。
    • 如果 dsize(0, 0),则 fx 必须提供,且 fx > 0
  • fy:沿垂直方向(高度)的缩放因子。
    • 如果 dsize 不为 (0, 0),则此参数不起作用。
    • 如果 dsize(0, 0),则 fy 必须提供,且 fy > 0
  • interpolation:插值方法。这是 resize 函数中最重要的参数之一,决定了像素值如何计算。OpenCV提供了多种插值算法,默认值为 cv2.INTER_LINEAR。本文后续章节将详细介绍这些方法。

返回结果:

  • dst:调整尺寸后的输出图像。与 src 具有相同的类型和通道数。

1.3 两种尺寸指定方式

cv2.resize 提供了两种主要方式来指定输出图像的尺寸:

方式一:指定绝对尺寸 dsize

直接给出目标图像的精确宽度和高度。此时,fxfy 参数将失效或可以省略。

“`python
import cv2
import numpy as np

创建一个示例图像 (200×150, 3通道)

image = np.zeros((150, 200, 3), dtype=np.uint8)
image[20:130, 30:170] = (0, 0, 255) # 绘制一个红色矩形

指定目标尺寸为 400×300

new_width = 400
new_height = 300
resized_image_abs = cv2.resize(image, (new_width, new_height))

print(f”原始图像尺寸: {image.shape[1]}x{image.shape[0]}”) # 宽度x高度
print(f”绝对尺寸调整后图像尺寸: {resized_image_abs.shape[1]}x{resized_image_abs.shape[0]}”)

cv2.imshow(“Original Image”, image)
cv2.imshow(“Resized by Absolute Size”, resized_image_abs)
cv2.waitKey(0)
cv2.destroyAllWindows()
“`

方式二:指定缩放因子 fxfy

通过原始图像的宽度和高度乘以 fxfy 来计算目标尺寸。此时,dsize 参数必须设置为 (0, 0)

“`python
import cv2
import numpy as np

image = np.zeros((150, 200, 3), dtype=np.uint8)
image[20:130, 30:170] = (0, 0, 255)

指定水平和垂直方向的缩放因子都为 2.0 (放大两倍)

scale_factor_x = 2.0
scale_factor_y = 2.0
resized_image_factor = cv2.resize(image, (0, 0), fx=scale_factor_x, fy=scale_factor_y)

print(f”原始图像尺寸: {image.shape[1]}x{image.shape[0]}”)
print(f”缩放因子调整后图像尺寸: {resized_image_factor.shape[1]}x{resized_image_factor.shape[0]}”)

cv2.imshow(“Original Image”, image)
cv2.imshow(“Resized by Scale Factor”, resized_image_factor)
cv2.waitKey(0)
cv2.destroyAllWindows()
“`

通常,如果目标尺寸是已知的固定值,我们倾向于使用方式一;如果需要根据原始尺寸按比例缩放(如放大两倍、缩小一半),则方式二更为方便。

第二章:核心理论——插值方法详解

插值是图像尺寸调整的核心技术。当我们将图像放大(上采样)时,需要创建新的像素;当我们将图像缩小(下采样)时,需要合并或丢弃像素。无论是哪种情况,都需要根据周围已知像素的值来“猜测”或“计算”新像素的值,这就是插值的作用。不同的插值算法在计算效率、图像平滑度、细节保留能力以及是否引入伪影等方面表现各异。

OpenCV提供了以下几种常用的插值方法:

  1. cv2.INTER_NEAREST:最近邻插值
  2. cv2.INTER_LINEAR:双线性插值 (默认)
  3. cv2.INTER_CUBIC:双三次插值
  4. cv2.INTER_AREA:区域插值
  5. cv2.INTER_LANCZOS4:Lanczos插值

接下来,我们将逐一深入探讨这些插值方法的原理、特点及适用场景。

2.1 cv2.INTER_NEAREST:最近邻插值

  • 原理:最简单粗暴的插值方法。对于目标图像中的每一个像素点,它会找到原始图像中距离它最近的像素点,并将该像素点的值直接赋给目标像素点。
  • 特点
    • 速度最快:计算量最小,执行效率最高。
    • 边缘锯齿化:由于直接复制像素值,放大时会产生明显的“马赛克”或“锯齿”效果,边缘不再平滑。
    • 信息丢失(下采样):在下采样时,可能直接跳过一些像素,导致信息丢失。
  • 适用场景
    • 对速度要求极高,而对图像质量要求不高的场景。
    • 处理二值图像或分类图像(如语义分割掩码),因为这类图像的像素值代表类别,不应该被平滑或混合。
    • 简单的预览或调试。
  • 示例效果:放大时图像边缘呈现阶梯状,像素块感明显。

2.2 cv2.INTER_LINEAR:双线性插值 (默认)

  • 原理:比最近邻插值更复杂,但效果更好。它考虑目标像素点在原始图像中对应的位置周围的 2×2 邻域(即四个最近的像素点)。目标像素点的亮度值通过这四个像素点的亮度值的加权平均得到,权重与目标点到这四个像素点的距离成反比。
  • 特点
    • 速度较快:虽然比最近邻慢,但计算量相对较小,在多数场景下都能满足实时性要求。
    • 图像平滑:生成的图像比较平滑,视觉效果比最近邻好很多,有效减少了锯齿感。
    • 细节模糊:在放大图像时,可能会引入一定的模糊,导致细节损失。
  • 适用场景
    • 通用场景:由于其良好的速度和相对不错的质量平衡,它是OpenCV中 resize 函数的默认插值方法,适用于大多数常规的图像缩放任务。
    • 中等质量的上采样和下采样。
  • 示例效果:放大时边缘比最近邻平滑,但整体感觉略微模糊。

2.3 cv2.INTER_CUBIC:双三次插值

  • 原理:比双线性插值更高级。它考虑目标像素点在原始图像中对应的位置周围的 4×4 邻域(即十六个最近的像素点)。通过一个三次多项式来计算加权平均值,从而得到目标像素点的亮度值。
  • 特点
    • 质量更高:生成的图像更加平滑和清晰,尤其是在放大图像时,细节保留更好,锯齿感极小。
    • 速度较慢:计算量是双线性的四倍(因为考虑16个像素),因此速度较慢。
    • 可能产生“振铃效应”:在图像的锐利边缘处,有时会产生轻微的“过冲”或“振铃”伪影。
  • 适用场景
    • 高质量上采样:当对图像放大后的质量有较高要求时,例如在专业图像处理、医疗影像或出版物中。
    • 要求平滑度的场景:需要最大限度减少锯齿感的应用。
  • 示例效果:放大时图像边缘非常平滑,细节过渡自然,但计算时间相对较长。

2.4 cv2.INTER_AREA:区域插值

  • 原理
    • 下采样时:此方法将目标像素点对应到原始图像中的一个区域,然后取该区域内所有像素的平均值作为目标像素点的值。它实际上是区域像素的重采样。
    • 上采样时:对于上采样,它等同于 INTER_NEARESTINTER_LINEAR 的效果,具体取决于缩放比例。
  • 特点
    • 下采样效果最佳:对于缩小图像,INTER_AREA 是公认的最佳方法,因为它有效地聚合了原始图像区域的信息,能够很好地避免“摩尔纹”和“走样”(aliasing)现象。
    • 速度快:下采样时通常比双线性、双三次更快。
    • 上采样不佳:不推荐用于放大图像,效果通常不如双线性或双三次。
  • 适用场景
    • 下采样(缩小图像):这是其主要优势和最佳应用场景,例如生成缩略图、为深度学习模型准备缩小后的输入图像。
  • 示例效果:缩小图像时,细节得到很好的保留,视觉上最清晰。放大时则可能显得比较生硬。

2.5 cv2.INTER_LANCZOS4:Lanczos插值

  • 原理:一种更高级的基于Sinc函数的卷积插值算法。它考虑目标像素点周围的 8×8 邻域(即64个像素点),通过一个复杂的数学函数(Lanczos核)进行加权平均。
  • 特点
    • 最高质量:在大多数情况下,Lanczos插值能够提供最高质量的图像缩放效果,无论是放大还是缩小,都能在保持锐度的同时减少锯齿。
    • 速度最慢:由于涉及64个像素的复杂计算,其计算成本最高,速度最慢。
    • 可能产生“振铃效应”:与双三次插值类似,在极端锐利的边缘处,也可能产生轻微的振铃效应。
  • 适用场景
    • 对图像质量要求极致的场景:例如专业图像编辑、高精度科学计算、电影制作等。
    • 需要同时兼顾锐度和平滑度的场景
  • 示例效果:提供最锐利、最平滑的图像,但计算时间最长。

2.6 插值方法总结与选择建议

插值方法 放大 (上采样) 缩小 (下采样) 速度 质量 (相对) 主要特点与注意事项
INTER_NEAREST 锯齿感强,马赛克化 锯齿感强,可能信息丢失 最快 最低 用于二值/分类图像,或对速度要求极高且质量不敏感的场景。
INTER_LINEAR 平滑,略有模糊 平滑,效果良好 较快 中等 默认选项,适用于大多数通用场景,兼顾速度与质量。
INTER_CUBIC 非常平滑,细节保留好,可能振铃 较好,可能振铃 较慢 较高 适用于高质量的上采样,追求更平滑的视觉效果。
INTER_AREA 不推荐,效果不佳 (近似最近邻或双线性) 效果最佳,有效避免走样,保留细节 较快 最高 (下采样) 强烈推荐用于下采样,生成缩略图,减少摩尔纹。
INTER_LANCZOS4 最高质量,锐度和平滑度兼顾,可能振铃 最高质量,锐度和平滑度兼顾,可能振铃 最慢 最高 适用于对图像质量有极致要求的专业级应用。

选择建议:

  • 缩小图像(下采样)时优先考虑 cv2.INTER_AREA。它通过区域平均有效避免了像素信息丢失和走样,能够生成最清晰、最不易失真的缩略图。
  • 放大图像(上采样)时
    • 如果对速度有较高要求且质量可接受,使用 cv2.INTER_LINEAR
    • 如果对质量有较高要求,希望图像更平滑、细节更丰富,使用 cv2.INTER_CUBIC
    • 如果对质量有极致要求,且不计较计算时间,使用 cv2.INTER_LANCZOS4
  • 处理二值图像或分类掩码时务必使用 cv2.INTER_NEAREST,以避免像素值被混合,导致类别信息失真。

第三章:实践出真知——代码示例与高级应用

3.1 演示不同插值方法的对比

“`python
import cv2
import numpy as np

1. 创建一个示例图像 (用于演示插值效果,带文字和图形)

创建一个白色背景图像

original_size = (200, 150) # 宽度x高度
img = np.full((original_size[1], original_size[0], 3), 255, dtype=np.uint8)

绘制一个红色矩形

cv2.rectangle(img, (20, 20), (80, 80), (0, 0, 255), -1)

绘制一个蓝色圆形

cv2.circle(img, (150, 70), 40, (255, 0, 0), -1)

添加文字

cv2.putText(img, “OpenCV”, (10, 140), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2)

cv2.imshow(“Original Image (200×150)”, img)

2. 定义目标放大尺寸

target_size_up = (400, 300) # 放大两倍

print(f”\n原始图像尺寸: {img.shape[1]}x{img.shape[0]}”)
print(f”目标放大尺寸: {target_size_up[0]}x{target_size_up[1]}”)

3. 使用不同的插值方法进行放大

interpolation_methods = {
“NEAREST”: cv2.INTER_NEAREST,
“LINEAR (Default)”: cv2.INTER_LINEAR,
“CUBIC”: cv2.INTER_CUBIC,
“AREA”: cv2.INTER_AREA,
“LANCZOS4”: cv2.INTER_LANCZOS4
}

resized_images_up = {}
for name, method in interpolation_methods.items():
resized = cv2.resize(img, target_size_up, interpolation=method)
resized_images_up[name] = resized
cv2.imshow(f”Upscale with {name}”, resized)
print(f”Upscale with {name} -> {resized.shape[1]}x{resized.shape[0]}”)

cv2.waitKey(0)
cv2.destroyAllWindows()

4. 定义目标缩小尺寸

target_size_down = (100, 75) # 缩小一半

print(f”\n目标缩小尺寸: {target_size_down[0]}x{target_size_down[1]}”)

5. 使用不同的插值方法进行缩小

resized_images_down = {}
for name, method in interpolation_methods.items():
resized = cv2.resize(img, target_size_down, interpolation=method)
resized_images_down[name] = resized
cv2.imshow(f”Downscale with {name}”, resized)
print(f”Downscale with {name} -> {resized.shape[1]}x{resized.shape[0]}”)

cv2.waitKey(0)
cv2.destroyAllWindows()
``
运行上述代码,您会看到不同插值方法在放大和缩小图像时产生的视觉差异:
* **放大时**:
NEAREST会有明显的锯齿和马赛克;LINEAR较为平滑但边缘会模糊;CUBICLANCZOS4则会提供更平滑、更锐利的边缘和细节,其中LANCZOS4通常效果最佳。AREA放大时效果不佳,可能会像NEAREST一样生硬。
* **缩小时**:
NEARESTLINEAR可能会导致细节丢失或产生摩尔纹;AREA会在保留细节和避免走样方面表现出色,图像看起来最清晰;CUBICLANCZOS4缩小效果也很好,但AREA` 在效率和避免走样方面通常更受推荐。

3.2 保持图片纵横比的尺寸调整

在许多应用中,我们不仅要调整图片尺寸,还要确保其原始的纵横比不被改变,以避免图像扭曲。这通常通过计算缩放比例并选择合适的尺寸,或者通过“填充”(padding)来实现。

方法一:通过缩放因子保持纵横比

“`python
import cv2
import numpy as np

image = cv2.imread(“your_image.jpg”) # 替换为您的图片路径
if image is None:
print(“Error: Could not load image.”)
# 创建一个示例图像以继续
image = np.zeros((300, 400, 3), dtype=np.uint8)
cv2.putText(image, “Sample Image”, (50, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

original_h, original_w = image.shape[:2]
target_max_side = 200 # 希望最长边为200像素

计算缩放比例

if original_h > original_w:
scale_factor = target_max_side / original_h
else:
scale_factor = target_max_side / original_w

计算新的宽度和高度,并取整

new_w = int(original_w * scale_factor)
new_h = int(original_h * scale_factor)

resized_image_aspect = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_AREA) # 缩小推荐AREA

print(f”原始尺寸: {original_w}x{original_h}”)
print(f”保持纵横比调整后尺寸: {new_w}x{new_h}”)

cv2.imshow(“Original”, image)
cv2.imshow(“Resized_Aspect_Ratio”, resized_image_aspect)
cv2.waitKey(0)
cv2.destroyAllWindows()
“`

方法二:填充(Letterboxing)保持纵横比

这种方法是将图像缩放到目标尺寸范围内,然后通过添加边框(通常是黑色或白色)来填充到最终的目标尺寸,使得图像不被拉伸,且完整地显示在一个特定大小的“画布”上。

“`python
import cv2
import numpy as np

def resize_with_padding(image, target_size=(224, 224), interpolation=cv2.INTER_LINEAR, pad_color=(0, 0, 0)):
“””
将图像调整到指定尺寸,并保持纵横比,通过填充边框实现。
:param image: 输入图像 (H, W, C)
:param target_size: 目标输出尺寸 (width, height)
:param interpolation: 插值方法
:param pad_color: 填充的颜色 (BGR)
:return: 调整并填充后的图像
“””
h, w = image.shape[:2]
target_w, target_h = target_size

# 计算缩放比例
scale = min(target_w / w, target_h / h)
new_w, new_h = int(w * scale), int(h * scale)

# 调整图像大小
resized_img = cv2.resize(image, (new_w, new_h), interpolation=interpolation)

# 计算填充量
pad_w = target_w - new_w
pad_h = target_h - new_h

# 计算左右和上下填充量
pad_left = pad_w // 2
pad_right = pad_w - pad_left
pad_top = pad_h // 2
pad_bottom = pad_h - pad_top

# 创建填充图像
padded_img = cv2.copyMakeBorder(resized_img, pad_top, pad_bottom, pad_left, pad_right,
                                cv2.BORDER_CONSTANT, value=pad_color)
return padded_img

使用示例

image = cv2.imread(“your_image.jpg”) # 替换为您的图片路径
if image is None:
print(“Error: Could not load image.”)
# 创建一个示例图像以继续
image = np.zeros((300, 500, 3), dtype=np.uint8)
cv2.putText(image, “Sample Image Long”, (50, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

target_fixed_size = (224, 224) # 目标固定尺寸 (例如,用于深度学习输入)

padded_image = resize_with_padding(image, target_fixed_size, interpolation=cv2.INTER_AREA)

print(f”原始尺寸: {image.shape[1]}x{image.shape[0]}”)
print(f”填充调整后尺寸: {padded_image.shape[1]}x{padded_image.shape[0]}”)

cv2.imshow(“Original”, image)
cv2.imshow(f”Padded to {target_fixed_size[0]}x{target_fixed_size[1]}”, padded_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
“`

3.3 在深度学习中的应用

在深度学习领域,resize 是数据预处理流程中不可或缺的一环。例如,将所有输入图像调整为VGGNet或ResNet等模型所需的224×224像素,或将YOLO/SSD等目标检测模型所需的图像调整为416×416或608×608。

示例:准备图像用于深度学习模型输入

“`python
import cv2
import numpy as np

假设这是从数据集中读取的一张图片

image_path = “your_image.jpg” # 替换为您的图片路径
img = cv2.imread(image_path)

if img is None:
print(f”Error: Could not load image from {image_path}. Using dummy image.”)
img = np.random.randint(0, 256, size=(640, 480, 3), dtype=np.uint8) # 创建一个随机图片

深度学习模型要求的输入尺寸

model_input_size = (224, 224) # 宽度x高度

通常使用 INTER_AREA 进行下采样,避免走样

如果模型对小物体检测敏感,可能需要更精细的插值

resized_for_model = cv2.resize(img, model_input_size, interpolation=cv2.INTER_AREA)

如果需要,可以将图像进行归一化(例如,像素值从0-255缩放到0-1)

normalized_image = resized_for_model.astype(np.float32) / 255.0

转换为模型所需的通道顺序 (例如,TensorFlow/PyTorch可能需要 (Batch, Height, Width, Channels) 或 (Batch, Channels, Height, Width) )

OpenCV默认是BGR,大多数模型是RGB,可能还需要颜色通道转换

例如,转换为RGB:

rgb_image = cv2.cvtColor(normalized_image, cv2.COLOR_BGR2RGB)

增加batch维度:

input_tensor = np.expand_dims(rgb_image, axis=0) # shape becomes (1, 224, 224, 3)

print(f”原始图像尺寸: {img.shape}”)
print(f”为模型调整后的图像尺寸: {resized_for_model.shape}”)
print(f”归一化后的图像数据类型: {normalized_image.dtype}”)

cv2.imshow(“Original”, img)
cv2.imshow(“Resized for DL Model”, resized_for_model)
cv2.waitKey(0)
cv2.destroyAllWindows()
“`

第四章:性能考量与最佳实践

4.1 性能与插值方法

正如我们之前讨论的,不同的插值方法具有不同的计算复杂度:

  • INTER_NEAREST: 最快
  • INTER_LINEAR: 较快
  • INTER_AREA: 较快 (下采样时通常与 LINEAR 接近,甚至更快)
  • INTER_CUBIC: 较慢
  • INTER_LANCZOS4: 最慢

在实时应用或处理大量图像时,选择合适的插值方法至关重要。例如,在视频处理中,即使是 INTER_LINEARINTER_CUBIC 之间的速度差异也可能导致帧率显著下降。因此,应根据实际需求在图像质量和计算性能之间取得平衡。

4.2 内存管理

图像尺寸调整会创建新的图像数组。如果频繁地对大型图像进行尺寸调整,或者在循环中创建大量临时图像,可能会导致内存消耗过大。

最佳实践:
* 及时释放资源:在Python中,当不再需要图像数组时,让垃圾回收机制自动处理即可。但如果在一个紧密的循环中处理,可以考虑手动删除 del resized_img 或确保变量被重新赋值以覆盖旧数据。
* 原地操作(In-place operations)cv2.resize 不支持原地操作,它总是返回一个新的图像。这意味着在调整尺寸后,原始图像仍然存在于内存中,直到被Python垃圾回收。
* 处理大型图像时分块:对于无法一次性加载到内存中的超大型图像,可以考虑分块读取、分块处理(resize),然后拼接。但这对于 resize 这样的全局操作较为复杂,通常更适用于卷积等局部操作。

4.3 错误处理与边界情况

  • 空图像:如果 src 图像为空(例如 cv2.imread 读取失败),cv2.resize 会报错。在调用 resize 之前,务必检查 src 是否有效(if img is None: ...)。
  • 无效尺寸:如果 dsizefx/fy 导致目标尺寸为零或负数,cv2.resize 会报错。确保计算出的目标尺寸是有效且合理的正整数。

4.4 其他注意事项

  • 通道数cv2.resize 会保留原始图像的通道数。如果输入是3通道彩色图,输出也是3通道;如果输入是单通道灰度图,输出也是单通道。
  • 数据类型cv2.resize 会保留原始图像的数据类型。通常输入是 np.uint8,输出也是 np.uint8。如果需要其他数据类型(例如浮点数进行归一化),需要额外进行类型转换。
  • 图像预加载:如果需要对同一批图像进行多次 resize 操作,并且这些图像本身较小,可以考虑先将它们全部加载到内存中,而不是每次都从磁盘读取,以减少I/O开销。

总结

cv2.resize 是OpenCV中一个看似简单实则功能强大的函数。掌握其参数,尤其是各种插值方法的原理、特点及适用场景,是进行高效且高质量图像尺寸调整的关键。

  • 记住下采样优先 cv2.INTER_AREA,因为它能有效避免走样,生成更清晰的缩略图。
  • 上采样时,根据需求权衡速度与质量,在 cv2.INTER_LINEAR (默认), cv2.INTER_CUBIC, cv2.INTER_LANCZOS4 之间选择。
  • 处理二值图或掩码时,务必使用 cv2.INTER_NEAREST
  • 在实际应用中,保持图像的纵横比通常是基本要求。

通过本文的详细讲解和代码示例,相信您已经对OpenCV resize 函数有了全面而深入的理解,能够根据不同的应用场景,灵活选择最合适的尺寸调整策略。在未来的计算机视觉项目中,这项技能将成为您不可或缺的利器。继续实践,不断探索,您将在图像处理的道路上走得更远!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部