使用Python,OpenCV缩放照片(忽略宽高比,保持宽高比)

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Python,OpenCV缩放照片(忽略宽高比,保持宽高比)相关的知识,希望对你有一定的参考价值。

这篇博客将介绍如何使用OpenCV调整图像大小。

调整图像的大小:缩小图像大小更有利一些(而且视觉上更吸引人一些),需要从图像中移除像素。增加图像的大小,则需要在其间“填补”不存在的像素值。

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

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

1. 效果图

1.1 保持宽高比效果图

原图 VS 缩小为1/2图 VS 放大2倍图效果图如下:
在这里插入图片描述

1.2 忽略宽高比效果图

在这里插入图片描述可以看出保持宽高比的缩放使得图片看起来比较规整,忽略图像的宽高比会使调整后的图像看起来像被压缩、扭曲或者挤压。

1.3 opencv各插值效果图

原图 VS cv2.INTER_NEAREST效果图如下,有块状的伪影
在这里插入图片描述
原图 VS cv2.INTER_LINEAR效果图如下:块状的伪影消失,图像看起来更平滑
在这里插入图片描述

原图 VS cv2.INTER_AREA效果图如下,块状的瑕疵又回来了
在这里插入图片描述
原图 VS cv2.INTER_CUBIC效果图如下,三次插值进一步消除了块状伪影
在这里插入图片描述
原图 VS cv2.INTER_LANCZOS4效果图如下,基本同cv2.INTER_CUBIC
在这里插入图片描述

2. 原理

  • cv2.resize(忽略宽高比)
  • imutils.resize(保持宽高比)
  • OpenCV中提供的插值方法(在需要对图像进行下采样或上采样时非常有用)

3. 源码

# USAGE
# python opencv_resize.py

# 导入必要的包
import argparse

import cv2
# 构建命令行参数及解析
# --image 输入图像的路径
import imutils

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, default="ymzyt.jpg",
                help="path to the input image")
args = vars(ap.parse_args())

# 加载原始图像并展示
image = cv2.imread(args["image"])
image = imutils.resize(image, width=400)
cv2.imshow("Original", image)
width = image.shape[1]
cv2.imshow("ratio 1/2", imutils.resize(image, width=int(width / 2)))
cv2.imshow("ratio 2", imutils.resize(image, width=width * 2))
cv2.waitKey(0)

cv2.imshow("Original", image)
width = image.shape[1]
height = image.shape[0]
cv2.imshow("no ratio 1/2", cv2.resize(image, (int(width / 2), int(height / 1)), interpolation=cv2.INTER_AREA))
cv2.imshow("no ratio 2", cv2.resize(image, (width * 2, height * 3), interpolation=cv2.INTER_AREA))
cv2.waitKey(0)

# 缩放图像为宽度200px,但是为了防止图像被挤压及扭曲,首先计算宽高比
r = 200.0 / image.shape[1]
dim = (200, int(image.shape[0] * r))

# 调整图像大小
resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
cv2.imshow("Resized (Width)", resized)

# 保持宽高比的缩放高度为100px
r = 100.0 / image.shape[0]
dim = (int(image.shape[1] * r), 100)

# 执行缩放
resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
cv2.imshow("Resized (Height)", resized)
cv2.waitKey(0)

# 每次缩放图像时都自动计算宽高比,并保持宽高比的缩放图像
resized = imutils.resize(image, width=200)
cv2.imshow("Resized via imutils", resized)
cv2.waitKey(0)

resized = imutils.resize(image, height=75)

# 插值函数的目标是检查像素的邻域,并使用这些邻域在不引入失真(或至少尽可能少的失真)的情况下光学地增大或减小图像的大小。
# - cv2.INTER_NEAREST 最近邻插值法,OpenCV默认执行该方法,它执行双线性插值-斜率截距形式;
# - cv2.INTER_AREA 最简单的插值方法,找到“最近的”像素并假设其值。该方法不需要计算相邻像素的加权平均值或应用复杂的规则,虽然这种方法快速简单,但调整大小后的图像质量往往相对较差,并可能导致“块状”伪影。

# 这俩种方法速度较慢(它们不再使用简单的线性插值,而是使用样条曲线),并且在正方形像素邻域上使用双三次插值。
# - cv2.INTER_CUBIC 计算4 x 4邻居
# - cv2.INTER_LANCZOS4 计算8 x 8邻居,很少见,

# 构建OpenCV中的插值方法List
methods = [
    ("cv2.INTER_NEAREST", cv2.INTER_NEAREST),  # 有块状的伪影
    ("cv2.INTER_LINEAR", cv2.INTER_LINEAR),  # 块状的伪影消失,图像看起来更平滑
    ("cv2.INTER_AREA", cv2.INTER_AREA),  # 块状的瑕疵又回来了
    ("cv2.INTER_CUBIC", cv2.INTER_CUBIC),  # 三次插值进一步消除了块状伪影
    ("cv2.INTER_LANCZOS4", cv2.INTER_LANCZOS4)]  # 基本同cv2.INTER_CUBIC

# 遍历插值方法
for (name, method) in methods:
    # 上采样,使用当前插值方法,放大图片3倍
    print("[INFO] {}".format(name))
    resized = imutils.resize(image, width=image.shape[1] * 2,
                             inter=method)
    cv2.imshow("Method: {}".format(name), resized)

cv2.waitKey(0)
cv2.destroyAllWindows()

参考

以上是关于使用Python,OpenCV缩放照片(忽略宽高比,保持宽高比)的主要内容,如果未能解决你的问题,请参考以下文章

为啥 flexbox 中的宽高比 CSS 属性有时会被忽略? [复制]

CSS3新增功能02

在 UIImageView 中应用适合图像的宽高比后如何知道图像大小

ImageView的学习和使用

ImageView的学习和使用

[SVG样式缩放样式而不被切断