Resize:最近邻插值、双线性插值、双三次插值

news2025/1/11 4:49:54

Resize:最近邻插值、双线性插值、双三次插值

    • Opencv resize函数
      • 1. 最近邻插值(INTER_NEAREST)
        • 1.1 原理
        • 1.2 代码实例
        • 1.3 简单的代码复现
        • 1.4 特点
      • 2. 双线性插值(INTER_LINEAR)(默认值)
        • 2.1 原理
        • 2.2 简单的代码复现
      • 3. 双三次插值(INTER_CUBIC)
      • 4. 三种方法的直观对比

Opencv resize函数

官方文档:Opencv resize()

void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );
参数含义: 
InputArray src     -原图像 
OutputArray dst    -输出图像 
Size dsize         -目标图像的大小 
double fx=0        -在x轴上的缩放比例 
double fy=0        -在y轴上的缩放比例 
int interpolation  -插值方式,有以下5种方式 

INTER_NEAREST      -最近邻插值 
INTER_LINEAR       -双线性插值 (默认使用) 
INTER_AREA         -区域插值。 
INTER_CUBIC        -三次样条插值,也叫立方插值(超过4*4像素邻域内的双三次插值)
INTER_LANCZOS4     -Lanczos插值(超过8*8像素邻域的Lanczos插值)

当不输入fx和fy时,函数会自动计算

fx = float(src.shape[1] / dsize[1])
fy = float(src.shape[0] / dsize[0])

python中cv2.resize默认的是INTER_LINEAR官方建议:如果是缩小图片,使用INTER_AREA插值算法看起来是最好的,如果是放大图片,可以选择INTER_CUBIC(慢)或INTER_LINEAR(快但效果还不错)。

官方原文:To shrink an image, it will generally look best with INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with INTER_CUBIC (slow) or INTER_LINEAR (faster but still looks OK).

1. 最近邻插值(INTER_NEAREST)

1.1 原理

最近邻插值,也称为零阶插值。计算原理为,目标图像位置直接采用与它最邻近位置的原始图像的像素点为其赋值

目标图像位置(dst_x, dst_y)最邻近的原始图像位置(src_x, src_y)的计算:src_x = int(dst_x / scale_x)src_y = int(dst_y / scale_y),其中scale_xscale_y分别表示在图像宽度方向和高度方向的缩放比例。

1.2 代码实例

使用一个灰度图实例进行放大缩小

import numpy as np
import cv2

# 生成3*3的灰度图
img = np.array([[1,2,3],[4,5,6],[7,8,9]], dtype=np.uint8)

# 放大一倍
resized_up = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_NEAREST)

# 缩小一倍
resized_down = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)

# 缩小一倍再放大一倍
resized_down_up = cv2.resize(resized_down, None, fx=2, fy=2, interpolation=cv2.INTER_NEAREST)

print(img, resized_up, resized_down, resized_down_up)
(array([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]], dtype=uint8),
 array([[1, 1, 2, 2, 3, 3],
        [1, 1, 2, 2, 3, 3],
        [4, 4, 5, 5, 6, 6],
        [4, 4, 5, 5, 6, 6],
        [7, 7, 8, 8, 9, 9],
        [7, 7, 8, 8, 9, 9]], dtype=uint8),
 array([[1, 3],
        [7, 9]], dtype=uint8)),
array([[1, 1, 3, 3],
       [1, 1, 3, 3],
       [7, 7, 9, 9],
       [7, 7, 9, 9]], dtype=uint8)

由上可知:

  • 当dsize不指定的时候,则由fx和fy计算后四舍五入得到
  • 对同一张图缩小再放大,与原图不会保持一致
1.3 简单的代码复现
  • 官方函数
import cv2

# 读取图像
img = cv2.imread('F:/Datas/kaggle/archive/test/apple/apple.jpg')

# 缩放尺寸
dim = (int(img.shape[1] * 2), int(img.shape[0] * 2))

# 使用最近邻插值缩放图像
resized = cv2.resize(img, dim, fx=2, fy=2, interpolation = cv2.INTER_NEAREST)

# 显示缩放后的图像
cv2.imshow("Original image", img)
cv2.imshow("Resized image", resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 将图片写入本地
cv2.imwrite("F:/Datas/kaggle/archive/test/apple/applex2.jpg", resized)
  • 简单的复现
def resizeNearestRGB(src, dsize, fx, fy):
    cols, rows = dsize
    dst = np.zeros((rows, cols, 3), dtype=np.uint8)

    for i in range(rows):
        for j in range(cols):
            x = int(j / fx)
            y = int(i / fy)
            dst[i, j][0] = src[y, x][0]
            dst[i, j][1] = src[y, x][1]
            dst[i, j][2] = src[y, x][2]

    return dst

img = cv2.imread('F:/Datas/kaggle/archive/test/apple/apple.jpg')

dim = (int(img.shape[1] * 2), int(img.shape[0] * 2))
new_image = resizeNearestRGB(img, dim, 2, 2)

cv2.imshow("Original image", img)
cv2.imshow("Resized image", new_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 比较两个矩阵是否相等
if np.array_equal(resized, new_image):
    print("两个矩阵相等")
else:
    print("两个矩阵不相等")
    
OUT: 两个矩阵相等

在这里插入图片描述

1.4 特点

由于是以最近的点作为新的插入点,因此边缘不会出现渐变过渡区域,这也导致缩放后的图像容易出现锯齿的现象

在这里插入图片描述

2. 双线性插值(INTER_LINEAR)(默认值)

2.1 原理

双线性插值,又称双线性内插。其核心思想是在x和y两个方向分别进行线性插值。

1) 将目标图像的位置(dst_x, dst_y)映射到原图P(src_x, src_y)中,但这时取得的是float格式的结果;

src_x = float(dst_x / scale_x)
src_y = float(dst_y / scale_y)

2)得到P点在原图中最邻近的4个点Q11Q12Q21Q22
在这里插入图片描述

3)首先在x方向进行两次线性插值得到R1R2两个点的像素值f(R1)f(R2),然后再在y方向一次线性插值得到最终点P的像素值f(P),将该值赋值给目标图像(dst_x, dst_y)注意此处如果先在y方向插值,再在x方向插值,其结果是一样的

在这里插入图片描述

在这里插入图片描述

2.2 简单的代码复现
  • 官方代码
import cv2

# 读取图像
img = cv2.imread('F:/Datas/kaggle/archive/test/apple/apple.jpg')

# 缩放尺寸
dim = (int(img.shape[1] * 2), int(img.shape[0] * 2))

# 使用最近邻插值缩放图像
resized = cv2.resize(img, dim, fx=2, fy=2, interpolation = cv2.INTER_LINEAR)

# 显示缩放后的图像
cv2.imshow("Original image", img)
cv2.imshow("Resized image", resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 将图片写入本地
cv2.imwrite("F:/Datas/kaggle/archive/test/apple/applex2.jpg", resized)
  • 简单的复现
def resizeNearestRGB(src, dsize, fx, fy):
    cols, rows = dsize
    dst = np.zeros((rows, cols, 3), dtype=np.uint8)

    for i in range(rows):
        for j in range(cols):
            x = j / fx
            y = i / fy
            x1, y1 = int(x), int(y)
            x2 = min(x1 + 1, src.shape[1] - 1)
            y2 = min(y1 + 1, src.shape[0] - 1)
            Q11, Q21 = src[y1, x1], src[y1, x2]
            Q12, Q22 = src[y2, x1], src[y2, x2]
            if x2 == x1:
                R1 = Q11
                R2 = Q12
            else:
                R1 = Q11 * (x2 - x)/(x2 - x1) + Q21 * (x - x1)/(x2 - x1)
                R2 = Q12 * (x2 - x)/(x2 - x1) + Q22 * (x - x1)/(x2 - x1)
            if y2 == y1:
                P = R1
            else:
                P = R1 * (y2 - y)/(y2 - y1) + R2 * (y - y1)/(y2 - y1)
            dst[i, j] = P

    return dst


image = cv2.imread('F:/Datas/kaggle/archive/test/apple/apple.jpg')

new_size = (int(image.shape[1] * 2), int(image.shape[0] * 2))
new_image = resizeNearestRGB(image, new_size, 2, 2)

cv2.imshow('new image', new_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

自己复现的代码得到的像素值和opencv中内部实现存在一点偏差,可能opencv内部有进行优化
在这里插入图片描述

双线性内插值算法放大后的图像质量较高,不会出现像素值不连续的情况,然而此算法具有低通滤波器的性能,使高频分量受损,所以可能会使图像轮廓在一定程序上变得模糊。

3. 双三次插值(INTER_CUBIC)

在这里插入图片描述

双立方插值是双线性插值的扩展,又称双三次插值,使用相邻的16(4x4)个像素点的加权之和进行插值,每个像素的权重由基于距离的函数取得。

双立方插值算法比双线性插值能更好地保留细节、增加锐度和清晰度,但是,它可能会导致波纹。

在这里插入图片描述

4. 三种方法的直观对比

三种方法的对比:25(5x5)个拼凑在一起的单位方块,颜色表示函数值,黑点是指定数据被插值的位置。双线性插值得到的图像在正方形边界处会有像素值突变现象。
在这里插入图片描述

参考

图像处理中常见的几种插值方法:最近邻插值、双线性插值、双三次插值(附Pytorch测试代码)

维基百科

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1388411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rust-解引用

“解引用”(Deref)是“取引用”(Ref)的反操作。取引用,我们有&、&mut等操作符,对应的,解引用,我们有操作符,跟C语言是一样的。示例如下: 比如说,我们有引用类型p:&i32;,那么可以用符…

[笔记]深度学习入门 基于Python的理论与实现(三)

代码仓库 gitee 3. 神经网络 神经网络的出现就是为了解决设定权重的工作,即机器自动从数据中学习,确定合适的、能符合预期的输入与输出的权重。 3.1 从感知机到神经网络 神经网络和感知机有很多共同点,这里主要介绍差异 3.1.1 神经网络例子…

数据库|数据库范式(待完成)

文章目录 数据库的范式数据库的基本操作什么是数据库的范式产生的背景(没有规范化的坏处/带来的问题)规范化表格设计的要求五大范式的作用——树立标准打个比方——桥的承载能力1NF(1范式)如何转换成合适的一范式 2NF(…

Flask 项目怎么配置并创建第一个小项目?附上完成第一个小案例截图

目录 1. 为什么要学习 flask? 2. flask 是什么? 3. flask 如何使用? 要安装 Flask,可以按照以下步骤进行: 4. 使用流程 4.1. 新建项目 4.1.1. 打开 pycharm,新建项目 4.1.2. 设置目录,并…

centos7 arm服务器编译安装PaddlePaddle

前言 随着国产服务器发展,部署项目需要用在国产服务器上,官方教程里面很多没有讲解到,安装过程中出现了各种各样的问题,以下是对官方教程的补充,有什么问题,欢迎指正! 一、环境准备 gcc: 8.2版…

Python 网络编程之TCP详细讲解

【一】传输层 【1】概念 传输层是OSI五层模型中的第四层,负责在网络中的两个端系统之间提供数据传输服务主要协议包括**TCP(传输控制协议)和UDP(用户数据报协议)** 【2】功能 **端到端通信:**传输层负责…

数学建模-预测人口数据

目录 中国09~18年人口数据 创建时间 绘制时间序列图 使用专家建模器 得到结果 预测结果 残差的白噪声检验 中国09~18年人口数据 创建时间 路径:数据-> 定义日期和时间 绘制时间序列图 使用专家建模器 看看spss最终判断是那个模型最佳的契合 得到结果 预…

什么是NTFS格式文件系统?Tuxera NTFS for Mac2024下载步骤

一般磁盘格式分为:FAT、FAT32、NTFS,这几种格式目前是我们最常遇到的文件系统格式,其中现在遇到最多的就是NTFS格式,为更好地了解这类文件系统格式,小编今天专门介绍一下什么是NTFS格式文件系统以及它的特点和局限性。…

网络安全ctf比赛/学习资源整理,【解题工具、比赛时间、解题思路、实战靶场、学习路线】推荐收藏!

对于想学习或者参加CTF比赛的朋友来说,CTF工具、练习靶场必不可少,今天给大家分享自己收藏的CTF资源,希望能对各位有所帮助。 CTF在线工具 首先给大家推荐我自己常用的3个CTF在线工具网站,内容齐全,收藏备用。 1、C…

Chapter 10 类的继承(上篇)

目的:了解三种继承方式,并清楚其中的差别 🎃🎃🎃🎃🎃🎃🎃🎃🎃🎃🎃🎃🎃🎃🎃…

【JVM】垃圾回收 GC

一、前言 垃圾回收(Garbage Collection,GC)是由 Java 虚拟机(JVM)垃圾回收器提供的一种对内存回收的一种机制,它一般会在内存空闲或者内存占用过高的时候对那些没有任何引用的对象不定时地进行回收。以避免…

imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!)

引言 在深度学习和计算机视觉的世界里,数据是模型训练的基石,其质量与数量直接影响着模型的性能。然而,获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此,数据增强技术应运而生,成为了解决这一问题的…

在uni-app中使用sku插件,实现商品详情页规格展示和交互。

商品详情 - SKU 模块 学会使用插件市场,下载并使用 SKU 组件,实现商品详情页规格展示和交互。 存货单位(SKU) SKU 概念 存货单位(Stock Keeping Unit),库存管理的最小可用单元,通…

电子签章服务器,如何解决无纸化最后一公里?

钉钉、飞书、企微、OA、ERP等主流企业办公系统,无法实现电子签章,往往审批后还要将合同文件打印出来再进行签章。实现无纸化办公的这最后一公里就成了难题。电子签章服务器的出现,提供了完美的解决方案。本文将从专业角度,探讨电子…

大模型压缩与优化的技术原理与创新方法

目录 前言1 模型压缩简介2 知识蒸馏3 模型剪枝3.1 结构化剪枝3.2 非结构化剪枝 4 模型量化4.1 浮点表示 vs 定点表示4.2 位数选择与性能影响4.3 量化技术 5 其他模型压缩方法5.1 Weight Sharing: 参数共享5.2 Low-rank Approximation: 低秩分解5.3 Architecture Search: 神经网…

C++ 设计模式之观察者模式

【声明】本题目来源于卡码网(题目页面 (kamacoder.com)) 【提示:如果不想看文字介绍,可以直接跳转到C编码部分】 【设计模式大纲】 前面的文章介绍了创建型模式和结构型模式,今天开始介绍行为型模式。 【简介】什么是…

Oracle AWR报告的生成和解读

Oracle AWR报告的生成和解读 一、AWR报告概念及原理 Oracle10g以后,Oracle提供了一个性能检测的工具:AWR(Automatic Workload Repository 自动工作负载库)这个工具可以自动采集Oracle运行中的负载信息,并生成与性能相…

评估文字识别准确性的方法与流程

随着信息技术的发展,文字识别技术在各个领域得到了广泛的应用。然而,在实际应用中,如何评估文字识别的准确性,一直是相关领域的一个难题。本文将介绍几种常用的文字识别准确性评估方法,以期为相关领域的研究提供参考。…

Excel 添加复选框或选项按钮(表单控件)

Excel 添加复选框或选项按钮(表单控件) 要添加复选框或选项按钮,需要使用功能区上的“开发工具”选项卡。 注意: 若要启用“开发工具”选项卡,请按照以下说明进行操作: 在 Excel 2010 和后续版本中,选择“…

主流视频压缩格式

主流的视频压缩格式有很多,它们各自适用于不同的应用场景,如在线流媒体、广播、存档等。 以下是一些广泛使用的视频压缩格式: H.264/AVC (Advanced Video Coding): 目前最为广泛使用的视频压缩标准之一,兼容性极佳,广泛…