【opencv】最近邻插值、双线性插值、双三次插值(三次样条插值)

article/2025/9/23 16:11:19

目录

  • 1. 最近邻插值
  • 2. 双线性插值
    • 1)简单理解
    • 2)一般性
  • 3. 双三次插值(三次样条插值)
  • 总结

b站 视频讲解 : https://www.bilibili.com/video/BV1wh411E7j9/


1. 最近邻插值

举个简单例子:一个 3 × 3 3 \times 3 3×3 的单通道图像,如下
在这里插入图片描述

如果想把该图像放大为 4 × 4 4 \times 4 4×4大小的图像,那么该怎么做呢?
那么第一步肯定想到的是先把4X4的矩阵先画出来再说,然后,矩阵的每个像素都是未知数,等待着我们去填充:

在这里插入图片描述

目标图像的像素值从哪里来来呢?当然是从原图中来,好,先填写目标图最左上角坐标为(0,0)的像素,,那么该坐标 对应 原图中的坐标可以由如下公式得出:

  • s r c X = d s t X ∗ ( s r c _ w i d t h / d s t _ w i d t h ) srcX=dstX * (src\_width / dst\_width) srcX=dstX(src_width/dst_width)
  • s r c Y = d s t Y ∗ ( s r c _ h e i g h t / d s t _ h e i g h t ) srcY = dstY * (src\_height / dst\_height) srcY=dstY(src_height/dst_height)

好了,套用公式,就可以找到对应的原图的坐标了
( 0 ∗ ( 3 / 4 ) , 0 ∗ ( 3 / 4 ) ) → ( 0 ∗ 0.75 , 0 ∗ 0.75 ) → ( 0 , 0 ) (0*(3/4),0*(3/4)) \quad \rightarrow \quad ( 0 *0.75, 0 * 0.75) \quad \rightarrow \quad (0,0) (0(3/4),0(3/4))(00.75,00.75)(0,0)

找到了源图的对应坐标,就可以把源图中坐标为 (0,0) 处的像素值 234 填进去 目标图的(0,0)这个位置了。

接下来,如法炮制, 寻找目标图中坐标为 (1,0) 的象素对应源图中的坐标,套用公式:
( 1 ∗ 0.75 , 0 ∗ 0.75 ) → ( 0.75 , 0 ) ( 1 * 0.75, 0 * 0.75 ) \quad \rightarrow \quad (0.75,0) (10.75,00.75)(0.75,0)

结果发现,得到的坐标里面竟然有小数,这可怎么办? 计算机里的图像可是数字图像,象素就是最小单位了,象素的坐标都是整数,从来没有小数坐标。这时候采用的一种策略就是采用四舍五入的方法(也可以采用直接舍掉小数位的方法),把非整数坐标转换成整数。这里按照四舍五入的方法就得到坐标(1,0),完整的运算过程就是这样的:
( 1 ∗ 0.75 , 0 ∗ 0.75 ) → ( 0.75 , 0 ) → ( 1 , 0 ) ( 1 * 0.75, 0 * 0.75 ) \quad \rightarrow \quad (0.75,0) \quad \rightarrow \quad (1,0) (10.75,00.75)(0.75,0)(1,0)
那么就可以再填一个象素到目标矩阵中了,同样是把源图中坐标为(1,0)处的像素值38填入目标图中的(1, 0) 位置。

依次填完每个象素,一幅放大后的图像就诞生:

在这里插入图片描述

这种放大图像的方法叫做最临近插值算法,这是一种最基本、最简单的图像缩放算法,效果也是最不好的,放大后的图像有很严重的马赛克,缩小后的图像有很严重的失真;效果不好的根源就是其简单的最临近插值方法引入了严重的图像失真,比如,当由目标图的坐标反推得到的源图的的坐标是一个浮点数的时候,采用了四舍五入的方法,直接采用了和这个浮点数最接近的象素的值,这种方法是很不科学的,当推得坐标值为 0.75的时候,不应该就简单的取为1,既然是0.75,比1要小0.25 ,比0要大0.75 ,那么目标象素值其实应该根据这个原图中虚拟的点四周的四个真实的点来按照一定的规律计算出来的,这样才能达到更好的缩放效果。双线型内插值算法就是一种比较好的图像缩放算法,它充分的利用了原图中虚拟点四周的四个真实存在的像素值来共同决定目标图中的一个像素值,因此缩放效果比简单的最邻近插值要好很多。


2. 双线性插值

根据于待求点P最近4个点的像素值,计算出P点的像素值。

1)简单理解

对于一个 目标像素,设置坐标通过反向变换得到的浮点坐标为 ( i + u , j + v ) (i+u,j+v) (i+u,j+v) (其中 i 、 j i、j ij均为浮点坐标的整数部分, u 、 v u、v uv 为浮点坐标的小数部分,是取值 [0,1) 区间的浮点数,则这个像素的值 f ( i + u , j + v ) f(i+u,j+v) f(i+u,j+v) 可由原图像中坐标为 ( i , j ) 、 ( i + 1 , j ) 、 ( i , j + 1 ) 、 ( i + 1 , j + 1 ) (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1) (i,j)(i+1,j)(i,j+1)(i+1,j+1)所对应的周围四个像素的值决定,即:

f ( i + u , j + v ) = ( 1 − u ) ( 1 − v ) f ( i , j ) + ( 1 − u ) v f ( i , j + 1 ) + u ( 1 − v ) f ( i + 1 , j ) + u v f ( i + 1 , j + 1 ) f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1) f(i+u,j+v)=(1u)(1v)f(i,j)+(1u)vf(i,j+1)+u(1v)f(i+1,j)+uvf(i+1,j+1)

其中 f ( i , j ) f(i,j) f(i,j) 表示源图像 ( i , j ) (i,j) (i,j) 处的的像素值,以此类推。

2)一般性

在这里插入图片描述

如上图,已知Q12,Q22,Q11,Q21,但是要插值的点为P点,这就要用双线性插值了,首先在x轴方向上,对R1和R2两个点进行插值,这个很简单,然后根据R1和R2对P点进行插值,这就是所谓的双线性插值。说明:下式中 f ( ∗ ) 为 ∗ f(*)为 * f()点处像素值。

首先在 x 方向进行线性插值,得到:

在这里插入图片描述

然后在 y 方向进行线性插值,得到:

在这里插入图片描述

也即点P处像素值:

在这里插入图片描述


3. 双三次插值(三次样条插值)

假设源图像A大小为mn,缩放K倍后的目标图像B的大小为MN,即K=M/m。A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一像素点(X,Y)的值,必须先找出像素(X,Y)在源图像A中对应的像素(x,y),再根据源图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加。

在这里插入图片描述

根据比例关系x/X=m/M=1/K,我们可以得到B(X,Y)在A上的对应坐标为A(x,y)=A(X*(m/M),Y*(n/N))=A(X/K,Y/K)。如图所示P点就是目标图像B在(X,Y)处对应于源图像A中的位置,P的坐标位置会出现小数部分,所以我们假设 P的坐标为P(x+u,y+v),其中x,y分别表示整数部分,u,v分别表示小数部分(蓝点到a11方格中红点的距离)。那么我们就可以得到如图所示的最近16个像素的位置,在这里用a(i,j)(i,j=0,1,2,3)来表示,如上图。

在这里插入图片描述

我们要做的就是求出BiCubic函数中的参数x,从而获得上面所说的16个像素所对应的权重W(x)。BiCubic基函数是一维的,而像素是二维的,所以我们将像素点的行与列分开计算。BiCubic函数中的参数x表示该像素点到P点的距离,例如a00距离P(x+u,y+v)的距离为(1+u,1+v),因此a00的横坐标权重i_0=W(1+u),纵坐标权重j_0=W(1+v),a00对B(X,Y)的贡献值为:(a00像素值)* i_0* j_0。因此,a0X的横坐标权重分别为W(1+u),W(u),W(1-u),W(2-u);ay0的纵坐标权重分别为W(1+v),W(v),W(1-v),W(2-v);B(X,Y)像素值为:

在这里插入图片描述

对待插值的像素点(x,y)(x和y可以为浮点数),取其附近的4x4邻域点(xi,yj), i,j = 0,1,2,3。按如下公式进行插值计算:

在这里插入图片描述


总结

  1. 最邻近插值:根据比例关系,得到目标像素 映射在 原图中的浮点像素坐标位置(小数表示),四舍五入,直接取值。

  2. 双线性插值:根据比例关系,得到目标像素 映射在 原图中的浮点像素坐标位置(小数表示),再利用双线性插值计算出目标像素点的像素值,其根据周围四个像素值和距离位置(小数表示的位置比例)关系得出。

  3. 双三次插值 (三次样条插值):根据比例关系,得到目标像素 映射在 原图中的浮点像素坐标位置(小数表示),取周围4x4=16个像素,根据位置关系(距离远近)计算出权重(这里有点像高斯滤波,只是不是用高斯公式计算权重)。最后把周围16个像素值算加权和,得出目标像素的像素值。


http://chatgpt.dhexx.cn/article/Iw5bsH6d.shtml

相关文章

挑战图像处理100问(27)——双三次插值

当我们需要对图像进行放大或缩小时,为了避免图像变形或失真,我们需要进行插值。插值是一种基于已知数据点,在这些数据点之间进行估计的方法。在图像处理中,常见的插值方法包括最邻近插值、双线性插值、双三次插值等。 双三次插值…

【图像超分辨(SR)】通俗直观彻底理解双线性插值、双三次插值及其作用

写在前面的一点话 网上讲解基本双线性插值、双三次线性插值的文章很多,但大部分都是只在讲为什么是这样,并不算非常通俗(起码对我来说需要额外查很多资料来补充理解)。很少有文章能够给初学者一些比较直观的理解,因此…

插值法(最邻近,双线性,双三次)的原理及实现

插值法(最邻近,双线性,双三次)的原理及实现 常用的插值方法有最邻近插值法、双现象插值法和双三次插值法等,主要用于图像的放大或缩小。 缩小图像(或称为下采样(subsampled) 或降采样&#xf…

表示关系x =y =z的c语言表达式为________.,为表示关系x≥y≥z,应使用C语言表达式____。...

为表焦距决定了画面的透视关系。 示关使用GREGRE ≥y≥桡神经沟位于 应C语言表关于脊柱正确的描写是() 建筑物或者其他设施以及建筑物上的搁置物、达式悬挂物发生( )造成他人损害的,所有人或者管理人应当承担民事责任,但能够证明自己没有过错的除外。 为表成对的脑颅…

C语言运算表达式整理

C语言的运算规则是按照运算符的优先级进行的,所以我们首先看一下C的运算优先级别 总结 最简单的优先级就是 算数运算符>关系运算符>逻辑运算符>赋值运算符 然后我们还要了解一个短路规则(特性) 短路规则:在整个逻辑表…

与数学式子对应的C语言表达式是(),与数学式子3乘以x的n次方/(2x-1)对应的C语言表达式是...

满意答案 lengwei241 2013.03.25 采纳率:43% 等级:13 已帮助:11778人 18 与数学式子3乘以x的n次方/(2x-1)对应的C语言表达式是 3*x^n/(2*x-1) 3*x**n/(2*x-1) 3*pow(x,n)*(1/(2*x-1)) 3*pow(n,x)/(2*x-1) 答案是3*pow(x,n)*(1/(2*x-1)) 为什么 解答:其中pow(x,n)为C语言…

C语言表达式和表达式的值

今天突然发现如果能很好的理解表达式和表达式的值的概念,可以使编程代码变的更整洁。很多时候我们总是忘记从最基本的概念开始考虑问题。我觉得我们有必要把C/C标准看下,在里面肯定有很多我们一直困惑的问题的答案。 C语言是基于结构化程序设计思想的程序…

以下c语言表达式与代数式计算结果,设有定义:float a=2,b=4,h=3;,以下C语言表达式中与代数式计算结果不相符的是...

设有定义:float a=2,b=4,h=3;,以下C语言表达式中与代数式计算结果不相符的是 设有式计算结Women in Britain, having some qualifications, were enfranchised until ______. 定义达式代数The usual rhyme scheme for the English or Shakespearean sonnet is( ). In “For …

与数学式对应的c语言表达式为,数学表达式“|x|4”对应的C语言表达式是“x-4||x4”。...

数学表达式“|x|4”对应的C语言表达式是“x-4||x4”。 数学式《莺莺传》故事的时代为( ) 表达人力资本的投资是提高技术水平的必要途径。() 对达式教育投资是人力资本的投资唯一重点。() 微商是以移动终端为载体,应的C语言表通过社交媒介手段,进行传播的…

C语言 运算符、表达式

运算符、表达式 1、 C语言运算符 算术运算符和算术表达式 (加)、—(减)、*(乘)、/(除)、%(取余,也叫模运算符,该运算符两侧都要求为整数&#xff…

c语言表达式语法问题,c语言表达式语法规则是什么_后端开发

c语言统计单词个数的方法_后端开发 在一篇文章中单词都是用空格隔开的,所以单词个数空格数1,c语言统计单词个数实际上转换成了统计文章中的空格数,可以用while和if来进行统计。 c语言表达式语法规则是什么 C语言表达式语法规则如下&#xff1…

c语言表达式成立,若有int y;则表示命题“y是偶数”成立的c语言表达式是多少...

满意答案 hoome_09 2017.12.28 采纳率:44% 等级:8 已帮助:263人 1. 若有int y;则表示命题“y是奇数”成立的C语言表达式是 (y%2 1) 。 2. 在C语言中,表示逻辑“真”值用(true) 表示。 3. 条件“2<x&…

C语言表达式用法快来看看

点击上方蓝字关注我,了解更多咨询 表达式是C语言的主体。在C语言中,表达式由操作符和操作数组成。最简单的表达式可以只含有一个操作数。根据表达式所含操作符的个数,可以把表达式分为简单表达式和复杂表达式两种,简单表达式是只含…

数学式子对应的c语言表达式是,把数学式写成C语言表达式

(1) 3.26*exp(x)1.0/3.0*pow((ab), 4) (2) 2*sqrt(x)(ab)/(3.0*sin(x)) (3) g*m1*m2/(r*r) (4) double pi 3.14 2.0*pi*r pi*r*r cos(45.0*pi / 180.0 ) (5) loan * rate * pow( (1rate) , month ) / ( pow( (1rate) , month) - 1) 扩展资料: 指针: 如…

C语言表达式专练

1、以下表达式值为3的是 A)16-13%10 B)23/2 C)14/3-2 D)(26)/(12-9) 2、设有说明语句:int k7,x12;则以下能使值为3的表达式是 A) x%(k%5) B)x%(k-k%5) C)x%k-k%5 D)(x%k)-(k%5) 3、若x、i、j和k都是int型变量,则执行表达式x(i4,j16,k32)后x的值为 A&…

快速求组合数

摘自https://www.jianshu.com/p/718a5ac26238 逆元快速幂解法 (一)基本概念 上面两种方法都使用了递归方法,递归方法有个缺陷,就是在数据较大时效率较低。所以这里要介绍一个种新的求组合算法。在了解此算法之前,要先了…

Java计算组合数以及生成组合排列

前言 组合数计算 公式法 逐个相除法(错误) 逐个相除法修正版 素数幂乘法 基本公式法 平方差连乘法 组合恒等法 简单递归法 杨辉三角法 杨辉三角优化法 二进制法 组合数计算小结 获取数组的组合排列 二进制法 基本迭代法 从后向前迭代法(Matlab版本…

[组合] 组合数计算四大算法模板(模板+卢卡斯定理)

文章目录 0. 前言1. 预处理组合数组合递推式2. 预处理阶乘逆元3. 卢卡斯定理4. 高精度组合数 0. 前言 组合数求解有很多种方式,不同的方式对应这不同的时间复杂度,难以程度也是不尽相同。根据数据范围选择对应的方法即可。 1. 预处理组合数组合递推式 …

组合数

1、定义:从m个不同元素中,任取n(n≤m)个元素并成一组,叫做从m个不同元素中取出n个元素的一个组合;从m个不同元素中取出n(n≤m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数。 2、公式:…