【opencv】最近邻插值、双线性插值、双三次插值(三次样条插值)
目录
- 1. 最近邻插值
- 2. 双线性插值
- 1)简单理解
- 2)一般性
- 3. 双三次插值(三次样条插值)
- 总结
1. 最近邻插值
举个简单例子:一个3×33 \times 33×3 的单通道图像,如下
如果想把该图像放大为 4×44 \times 44×4大小的图像,那么该怎么做呢?
那么第一步肯定想到的是先把4X4的矩阵先画出来再说,然后,矩阵的每个像素都是未知数,等待着我们去填充:
目标图像的像素值从哪里来来呢?当然是从原图中来,好,先填写目标图最左上角坐标为(0,0)的像素,,那么该坐标 对应 原图中的坐标可以由如下公式得出:
- srcX=dstX∗(src_width/dst_width)srcX=dstX * (src\_width / dst\_width)srcX=dstX∗(src_width/dst_width)
- srcY=dstY∗(src_height/dst_height)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))→(0∗0.75,0∗0.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)(1∗0.75,0∗0.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)(1∗0.75,0∗0.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、ji、ji、j均为浮点坐标的整数部分,u、vu、vu、v 为浮点坐标的小数部分,是取值 [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)vf(i,j+1)+u(1−v)f(i+1,j)+uvf(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)=(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,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。按如下公式进行插值计算:
总结
最邻近插值:根据比例关系,得到目标像素 映射在 原图中的浮点像素坐标位置(小数表示),四舍五入,直接取值。
双线性插值:根据比例关系,得到目标像素 映射在 原图中的浮点像素坐标位置(小数表示),再利用双线性插值计算出目标像素点的像素值,其根据周围四个像素值和距离位置(小数表示的位置比例)关系得出。
双三次插值 (三次样条插值):根据比例关系,得到目标像素 映射在 原图中的浮点像素坐标位置(小数表示),取周围4x4=16个像素,根据位置关系(距离远近)计算出权重(这里有点像高斯滤波,只是不是用高斯公式计算权重)。最后把周围16个像素值算加权和,得出目标像素的像素值。
【opencv】最近邻插值、双线性插值、双三次插值(三次样条插值)相关推荐
- matlab spline三次样条插值x,Spline(三次样条插值)
关于三次样条插值,计算方法比较复杂,但是静下心来仔细研究也是可以理解的. 本文借鉴文章来源:http://www.cnki.com.cn/Article/CJFDTotal-BGZD200611035 ...
- 拉格朗日插值、分段线性插值、三次样条插值
本篇主要介绍在三种插值方法:拉格朗日插值.分段线性插值.三次样条插值,以及这三种方法在matlab中如何实现. 1.拉格朗日插值: 1.1基本原理:先构造一组基函数: 是次 ...
- 计算方法:三次样条插值原理
无论是牛顿插值还是拉格朗日插值,都只能保证在节点处的函数值没有误差.hermite插值更加复杂,可以保证一阶导数也连续,目前常用的是三次样条插值 一.三次样条插值概念 不超过3次 节点处无误差 一阶导 ...
- 【20220207】【信号处理】三次样条插值原理详解
方程组的求解本文不做介绍. 一.三次样条插值 1. 定义 三次样条插值(Cublic Spline Interpolation),简称 Spline 插值,是通过一系列样本点的光滑曲线,数学上通过求解 ...
- 数学建模准备 插值(拉格朗日多项式插值,牛顿多项式插值,分段线性插值,分段三次样条插值,分段三次Hermite插值)
文章目录 摘要(必看) 0 基础概念 什么是插值 插值用途 什么是拟合 插值和拟合的相同点 插值和拟合的不同点 1 常用的基本插值方法 1.1 多项式插值法 1.1.1 拉格朗日多项式插值法 多项式插 ...
- python三次样条插值拟合的树行线_数学建模笔记——插值拟合模型(一)
啊好像距离上次写作又过了七天,啊好像我之前计划的一周两三篇,啊辣鸡小说毁我青春,啊我是一只可怜的鸽子. 不管怎样,我又回来了,并坚定地更新着hhh.再过两三天就是我们学校数学建模选拔,再过八九天就是期 ...
- [数值分析拟合]Matlab三次样条插值拟合数据
三次样条插值是一种运用极为广泛的工程插值算法,本文章编写的函数默认使用端点处的导数值代替给定的两端点的导数值使用三转角构造法进行插值(该函数也可传入端点导数数值进行分析),对数据进行方便而迅速的拟合( ...
- 清风数学建模学习笔记——应用matlab实现分段三次埃尔米特(Hermite)插值与三次样条插值
插值算法 数模比赛中,常常需要根据已知的函数点进行数据.模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,模拟产生一些新的但又比较靠谱的值来满足需求 ...
- 三次样条插值原理及openCV实现三种边界条件(CSDN为数不多的正确版本)
没有自定义目录标题 前情总结 算法介绍及原理解析 论证边界问题 边界条件介绍 公式推导 方程组 算法步骤 代码实现 前情总结 同事在工作中遇到需要样条插值的情况,帮他找实现代码的时候想根据博客推一遍原 ...
最新文章
- Unity Shader——Writing Surface Shaders(2)——Custom Lighting models in Surface Shaders
- .NET的Snk使用方法
- 腾讯+字节+阿里面经真题汇总,Android篇
- idea配置的导入导出
- JSLint JavaScript代码质量审查工具汉化中文版隆重发布
- mac os虚拟机镜像_为旧型Mac电脑配置支持OS 9的网络启动
- js 数组、对象转json 以及json转 数组、对象
- 基于 element ui 之 ui-tooltip 组件
- java(6)String Builder和String Joiner
- STM32 LL库延时函数 LL_mDelay解析
- Android实现一键开启自由窗口、分屏、画中画模式——自由窗口模式
- 一些常用的英文写作网站
- php在文本框显示图片,多张图片上传后在页面上可以显示图片,在文本框显示地址怎么解决啊...
- Windows内存清理工具实现——从现象到本质
- PySpark——随机森林分类案例
- 在windows系统写脚本,如何去掉回车换行符
- DHU Matlab Experiment【7】考试复盘
- C语言:输入一串字符串,统计字符串中有多少个数字
- 数学建模——数据分析、描述性统计
- spring异常java.lang.IllegalStateException