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

常用的插值方法有最邻近插值法、双现象插值法和双三次插值法等,主要用于图像的放大或缩小。

缩小图像(或称为下采样(subsampled) 或降采样(downsampled) ) 的主要目的有两个: 1、 使得图像符合显示区域的大小; 2、 生成对应图像的缩略图。

放大图像(或称为上采样(upsampling) 或图像插值(interpolating) ) 的主要目的是放大原图像,从而可以显示在更高分辨率的显示设备上。

一、最邻近插值法

最邻近插值(The nearest interpolation)即是选取一个最靠近的像素为它的像素值,这是最简单的一种插值方法,不需要计算。在待求像素的四邻像素中,将距离待求像素最近的邻接像素灰度值赋予待求像素。设i+u, j+v (i, j为正整数, u, v为大于零小于1的小数, 下同)为待求象素坐标, 则待求象素灰度的值 f(i+u, j+v) 如下图所示:

如果(i+u, j+v)落在A区,即u<0.5, v<0.5,则将左上角象素的灰度值赋给待求象素,同理,落在B区则赋予右上角的象素灰度值,落在C区则赋予左下角象素的灰度值,落在D区则赋予右下角象素的灰度值。

特点:最邻近元法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。

代码块:

import cv2
import numpy as np
def function(img):height,width,channels =img.shapeemptyImage=np.zeros((800,800,channels),np.uint8)sh=800/heightsw=800/widthfor i in range(800):for j in range(800):x=int(i/sh)y=int(j/sw)emptyImage[i,j]=img[x,y]return emptyImageimg=cv2.imread("lenna.png")
zoom=function(img)
print(zoom.shape)
cv2.imshow("nearest interp",zoom)
cv2.imshow("image",img)
cv2.waitKey(0)

二、双线性插值法

双线性插值(Bilinear interpolation):已知X-Y平面内四个像素点的坐标 (x0, y0) 、(x1, y0)、(x0, y1) (x1, y1),要得到四点构成 区间内某一点上的像素值。

2.1单线性插值

由简入难,先了解下单线性插值的原理:

已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值。如下图所示:

单线性插值用一句话概括就是用x和x0,x1的距离作为一个权重,用于y0和y1的加权。双线性插值本质上就是在两个方向上做线性插值。

2.2双线性插值

在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。如下图所示:

假如我们想得到未知函数 f 在点 P = (x, y) 的值,假设我们已知函数 f 在 Q11 = (x1, y1), Q12 = (x1, y2), Q21 = (x2, y1) , Q22 = (x2, y2) 四个点的值。最常见的情况,f就是一个像素点的像素值。分别在 x 、y方向做两次单线性插值,得到:

由于图像双线性插值只会用相邻的4个点, 因此上述公式的分母都是1。

特点:1、如果源图像和目标图像的原点(0, 0) 均选择左上角, 然后根据插值公式计算目标图像每点像素, 假设你需要将一幅5x5的图像缩小成3x3, 那么源图像和目标图像各个像素之间的对应关系如下:

即如果源图像和目标图像的原点(0, 0) 均选择左上角(或者右下角),那么有可能能会出现最右边和最下边的像素实际上并没有参与计算,而且目标图像的每个像素点计算出的灰度值也相对于源图像偏左偏上的情况。如果要解决这一问题,就需要将源图像和目标图像几何中心的对齐。

要通过双线性插值的方法计算出dst中每一个像素点的像素值,需要通过dst像素点的坐标对应到src图像当中的坐标,然后通过双线性插值的方法算出src中相应坐标的像素值。二者的坐标对应关系为:

srcX=dstX* (srcWidth/dstWidth) ,

srcY = dstY * (srcHeight/dstHeight)

考虑到如果将源图像和目标图像几何中心的对齐,如保持src图像不动,仅移动dst图像,则移动距离一定是1/2*(src_size-dst_size),那么上式可以修正为:

srcX=dstX* (srcWidth/dstWidth)+0.5*(srcWidth/dstWidth-1)

srcY = dstY* (srcHeight/dstHeight)+0.5*(srcHeight/dstHeight-1)

证明过程如下:

2、双线性插值运算过程存在着大量的浮点数运算,相对而言是一个较为耗时的过程,直接进行计算的话,由于计算的srcX和srcY 都是浮点数,后续会进行大量的乘法,而图像数据量又大,速度不会理想,解决思路是:浮点运算→→整数运算→→”<<左右移按位运算”。

3、没有灰度不连续的缺点, 图像看起来更光滑。

代码块:

import numpy as np
import cv2'''
python implementation of bilinear interpolation
'''
def bilinear_interpolation(img,out_dim):src_h, src_w, channel = img.shapedst_h, dst_w = out_dim[1], out_dim[0]print ("src_h, src_w = ", src_h, src_w)print ("dst_h, dst_w = ", dst_h, dst_w)if src_h == dst_h and src_w == dst_w:return img.copy()dst_img = np.zeros((dst_h,dst_w,3),dtype=np.uint8)scale_x, scale_y = float(src_w) / dst_w, float(src_h) / dst_hfor i in range(3):for dst_y in range(dst_h):for dst_x in range(dst_w):# find the origin x and y coordinates of dst image x and y# use geometric center symmetry# if use direct way, src_x = dst_x * scale_xsrc_x = (dst_x + 0.5) * scale_x-0.5src_y = (dst_y + 0.5) * scale_y-0.5# find the coordinates of the points which will be used to compute the interpolationsrc_x0 = int(np.floor(src_x))src_x1 = min(src_x0 + 1 ,src_w - 1)src_y0 = int(np.floor(src_y))src_y1 = min(src_y0 + 1, src_h - 1)# calculate the interpolationtemp0 = (src_x1 - src_x) * img[src_y0,src_x0,i] + (src_x - src_x0) * img[src_y0,src_x1,i]temp1 = (src_x1 - src_x) * img[src_y1,src_x0,i] + (src_x - src_x0) * img[src_y1,src_x1,i]dst_img[dst_y,dst_x,i] = int((src_y1 - src_y) * temp0 + (src_y - src_y0) * temp1)return dst_imgif __name__ == '__main__':img = cv2.imread('lenna.png')dst = bilinear_interpolation(img,(700,700))cv2.imshow('bilinear interp',dst)cv2.waitKey()

三、双三次插值法

双三次插值又称立方卷积插值。三次卷积插值是一种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值,不仅考虑到4 个直接相邻点的灰度影响,而且考虑到各邻点间灰度值变化率的影响。三次运算可以得到更接近高分辨率图像的放大效果,但也导致了运算量的急剧增加。

数学原理如下:

特点:双三次曲线插值方法计算量最大,但后的图像效果最好。这种算法是一很常见的算法,普遍用在图像编辑软件、打印机驱动和数码相机上。

代码块参考资料:https://blog.csdn.net/u013185349/article/details/84841202?utm_term=python%E6%9C%80%E9%82%BB%E8%BF%91%E6%8F%92%E5%80%BC&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-2-84841202&spm=3001.4430

参考资料:
最邻近插值法:
https://blog.csdn.net/qq_25015749/article/details/106288238

双线性插值法:
https://blog.csdn.net/weixin_36670529/article/details/103125041
https://www.cnblogs.com/yssongest/p/5303151.html

双三次插值法:
https://blog.csdn.net/nandina179/article/details/85330552
https://blog.csdn.net/qq_29058565/article/details/52769497
https://blog.csdn.net/u013185349/article/details/84841202?utm_term=python%E6%9C%80%E9%82%BB%E8%BF%91%E6%8F%92%E5%80%BC&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-2-84841202&spm=3001.4430

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

  1. 双线性 双三次 和基于lanczos 的插值算法

    三者相同点 双线性 双三次 lanczos插值 都是首先找到插值后点与原图中亚像素点后,通过不同的映射函数进行求解. 三者本质上没有任何区别,区别只是求解函数的拟合方式不同,努力去cover住最真实的 ...

  2. 【图像】插值方法原理(最近邻,双线性,双三,兰索斯)

    插值流程分为以下几步: 1)计算放缩比例.比如原图是2x2,现在放大到3x3,那么放缩比例就是3/2. 2)计算现在图片上每个像素对应到原图哪个像素.比如(2, 2)的像素对应到原图就是(2/(3/2 ...

  3. 第2章 Python 数字图像处理(DIP) --数字图像基础3 - 图像内插 - 最近邻内插 - 双线性插值 - 双三次内插 - 图像放大

    目录 图像内插 放大图像 图像内插 内插通常在图像放大.缩小.旋转和几何校正等任务中使用.内插并用它来调整图像的大小(缩小和放大),缩小和放大基本上采用图像重取样方法 最近邻内插,这种方法将原图像中最 ...

  4. 数字图像处理学习笔记(七)——用Pycharm及MATLAB实现三种图像内插法(最近邻内插法、双线性内插法、双三次内插法)

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声.增强.复原.分割.提取特征等处理的方法和技术.本专栏将以学习笔记形式对数字图像处理的重点基础知识进行总结 ...

  5. 【数字图像处理】图像内插“双三次内插法 双三次插值 Bicubic interpolation”(cv2.resize、cv.INTER_CUBIC)

    文章目录 基本原理 代码 引用自:<数字图像处理> 基本原理 引用自:https://baike.baidu.com/item/%E5%8F%8C%E4%B8%89%E6%AC%A1%E6 ...

  6. python中单双三引号区别_python基础题

    1.简述列举了解的编程语言及语言之间的区别? 解释型语言:python,javaScript,Shell 执行的时候在翻译 优点:开发效率高, 缺点:运行速度慢 编译型:c,c++ 只翻译一次 优点: ...

  7. cas:174899-82-2|1-乙基-3-甲基咪唑双(三氟甲磺酰)亚胺|EMIMTFSI

    cas:174899-82-2|1-乙基-3-甲基咪唑双(三氟甲磺酰)亚胺|EMIMTFSI 中文名 1-乙基-3-甲基咪唑双三氟甲磺酰亚胺盐 英文名 1-Ethyl-3-Methylimidazol ...

  8. 利用gdal的RasterIO进行最近邻、双线性、三次卷积重采样的重采样

    下面是根据<GDAL源码剖析与开发指南>上面对RasterIO的常规用法,该书使用的gdal版本比较老,新版的gdal版本已经可以支持RasterIO进行最近邻.双线性.三次卷积重采样的重 ...

  9. 三种图像内插法(最近邻内插法、双线性内插法、双三次内插法)的做法 代码实现

    参考博客 数字图像处理学习笔记(四)--数字图像的内插.度量.表示与质量_闭关修炼--暂退的博客-CSDN博客 数字图像处理学习笔记(七)--用Pycharm及MATLAB实现三种图像内插法(最近邻内 ...

最新文章

  1. MXNET源码中NDArray数据的获取和打印
  2. CRM系统助力企业找到最大盈利客户
  3. NetTiers中的一些内置对象及关系
  4. asp.net弹出div层,并把弹出层上的值赋值给界面
  5. memory matlab,memory – 在MATLAB中处理大量结构
  6. 核磁共振波谱分析_实验室各种仪器原理动图剖析,这么多分析仪器原理,1次搞清楚了...
  7. php面试hr要看你的项目,昨晚hr给了我一个面试题,说过了就安排我面试
  8. 我想在 2012 储备的技术
  9. redhat rpmforge epel 安装源配置
  10. java 栈 大小_java – JVM堆栈大小规范
  11. F - A Simple Problem with Integers(线段树)
  12. 天津计算机本科学校有哪些专业吗,天津哪些大学有人工智能专业
  13. oracle 去除空值函数,Oracle学习笔记:删除数据空格(trim、ltrim、rtrim函数)
  14. 银行计算机岗位招聘简历,这才是HR筛选银行简历的正确打开方式!
  15. 试验数据管理系统TDM与SDM
  16. python基础入门小结(1)
  17. puzzle(105)幻方、幻圆、拉丁方
  18. 记录一次Win10莫名其妙被植入一个恶意软件
  19. 中科创达旗下Rightware正式发布首个一体化汽车HMI工具链Kanzi One
  20. Oracle中的触发器(trigger)

热门文章

  1. 在已有项目中集成mars3d注意事项(vue3和vue2技术栈下)
  2. 几种经典非线性滤波算法简单概括(EKF,UKF,CKF,PF)
  3. Oracle入门笔记(三)——Oracle数据类型
  4. Revit server安装配置
  5. 2012-03-28-1
  6. bzoj 2054 并查集
  7. Docker Daemon
  8. [云原生专题-12]:容器 - Ubuntu/CentOS平台没有ifconfig/ping工具的解决办法
  9. 等级保护和分级保护区别与联系
  10. 数字手势识别App--(2)图像处理