基于Python实现二维图像双线性插值
作者:为为为什么 发布时间:2023-08-13 07:46:45
在对二维数据进行 resize / mapping / 坐标转换等操作时,经常会将原本的整数坐标变换为小数坐标,对于非整数的坐标值一种直观有效的插值方式为双线性插值。
插值简介
双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
双线性插值作为数值分析中的一种插值算法,广泛应用在信号处理,数字图像和视频处理等方面。
假设我们出现了需要在四个相邻正方形整数点(A,B,C,D)坐标中间(正方形范围内)选择一个点(a,b)取近似值的情形。
此时我们已知的是四个点的数值VA,VB,VC,VD,给定小数坐标E(a,b),0≤a,b≤1,如何插值求解E点的数值呢,解决类似问题的方法统称为插值,上图展示公式为双线性插值的计算方法。
最近邻法 (Nearest Interpolation)
一种最简便的方法为最近邻法,直接取与当前点距离最近的点的值作为插值结果:
其中 roundroundround 为四舍五入的取整操作,方法简便速度极快,但往往不够精细
双三次插值 (Bicubic interpolation)
双三次插值是用原图像中16(4*4)个点计算新图像中1个点,效果比较好,但是计算代价过大。
双线性插值 (Bilinear Interpolation)
使用一个点进行插值过于粗暴,16个点又过于繁琐,那就使用EEE点周围4个点的数值来近似求解,这是一种平衡了计算代价和插值效果的折中方案,也是各大变换库的默认插值操作。
双线性插值
通过观察上述动图(可以动手挪一挪)可以清晰地看到,双线性插值本质就是把四个角落的数值按照正方形面积的比例线性加权后的结果。
好吧一句话已经把数学的核心部分讲完了
那么既然理解了本质,数学公式就好写了:
python实现
在实现时当然 for 循环 * 可以解决一切问题,但总归是不太优雅,我们尝试使用 numpy 操作完成双线性插值
假设原始图像 image
,变换后的小数坐标 X 矩阵 x_grid
,Y 矩阵 y_grid
,那么可以使用如下的 bilinear_by_meshgrid
函数快速双线性插值,已经处理好了边界,可以放心使用。
def bilinear_by_meshgrid(image, x_grid, y_grid):
# Ia, Wd Ic, Wb
# (floor_x, floor_y) (ceil_x, floor_y)
#
# (x, y)
#
# Ib , Wc Id, Wa
# (floor_x, ceil_y) (ceil_x, ceil_y)
#
assert image.shape == x_grid.shape == y_grid.shape
assert image.ndim == 2
H, W = image.shape[:2]
floor_x_grid = np.floor(x_grid).astype('int32')
floor_y_grid = np.floor(y_grid).astype('int32')
ceil_x_grid = floor_x_grid + 1
ceil_y_grid = floor_y_grid + 1
if np.max(ceil_x_grid) > W -1 or np.max(ceil_y_grid) > H -1 or np.min(floor_x_grid) < 0 or np.min(floor_y_grid) < 0:
print("Warning: index value out of original matrix, a crop operation will be applied.")
floor_x_grid = np.clip(floor_x_grid, 0, W-1).astype('int32')
ceil_x_grid = np.clip(ceil_x_grid, 0, W-1).astype('int32')
floor_y_grid = np.clip(floor_y_grid, 0, H-1).astype('int32')
ceil_y_grid = np.clip(ceil_y_grid, 0, H-1).astype('int32')
Ia = image[ floor_y_grid, floor_x_grid ]
Ib = image[ ceil_y_grid, floor_x_grid ]
Ic = image[ floor_y_grid, ceil_x_grid ]
Id = image[ ceil_y_grid, ceil_x_grid ]
wa = (ceil_x_grid - x_grid) * (ceil_y_grid - y_grid)
wb = (ceil_x_grid - x_grid) * (y_grid - floor_y_grid)
wc = (x_grid - floor_x_grid) * (ceil_y_grid - y_grid)
wd = (x_grid - floor_x_grid) * (y_grid - floor_y_grid)
assert np.min(wa) >=0 and np.min(wb) >=0 and np.min(wc) >=0 and np.min(wd) >=0
W = wa + wb + wc + wd
assert np.sum(W[:, -1]) + np.sum(W[-1, :]) == 0
wa[:-1, -1] = ceil_y_grid[:-1, -1] - y_grid[:-1, -1]
wb[:-1, -1] = y_grid[:-1, -1] - floor_y_grid[:-1, -1]
wb[-1, :-1] = ceil_x_grid[-1, :-1] - x_grid[-1, :-1]
wd[-1, :-1] = x_grid[-1, :-1] - floor_x_grid[-1, :-1]
wd[-1, -1] = 1
W = wa + wb + wc + wd
assert np.max(W) == np.min(W) == 1
res_image = wa*Ia + wb*Ib + wc*Ic + wd*Id
return res_image
该函数集成在我自己的python库 mtutils
中,可以通过:
pip install mtutils
直接安装,之后可以直接引用:
from mtutils import bilinear_by_meshgrid
来源:https://juejin.cn/post/7107479950084538376
猜你喜欢
- asp 中处理文件上传以及删除时常用的自定义函数:删除文件,建立目录的程序,根据原文件名生成新的随机文件名,CMS替换函数,将所有开始,结束
- 动态变量名赋值在使用 tkinter 时需要动态生成变量,如动态生成 var1...var10 变量。使用 exec 动态赋值exec 在
- zhanglunray 问:我在mzzx_pic这个层设置了左边距,在ie里显示是正常的,但是在ff里显示时margin-left却没有起到
- 1.建立Recordset对象 代码如下:Dim objMyRst Set objMyRst=Server.C
- 相对于 Ajax,服务端 XMLHTTP 就是在服务端使用 XMLHttpRequest 对象了。虽然说,在服务端使用异步请求是比较不方便的
- 先看看CSS框架的利与弊前段时间一直在讨论CSS框架。很多朋友看了那三篇文章后提了不少自己意见。特别是一位北京的朋友A君,他有一个小的团体,
- 在如今的Web设计中,图片的应用是必不可少的,为了更好地设计网站效果,大体积的图片被越来越多地应用到Web设计中来,所以,更好地优化图片文件
- 代码如下:'返回某年总共有多少天 Function DayOfYear(ByVal y) DayOfYear = DatePart(
- 我们有时候看到一些文章因为一行的字符超长而把一些表格或DIV撑开或字符写到溢出了.如何防止表格防止撑开,表格不被内容撑开,单行字符超长div
- 目录:分析和设计组件编码实现和算法用 Ant 构建组件测试 JavaScript 组件本期,我们要讨论的话题是 JavaScript 的测试
- html页面一般都会指定一个编码,如何获取到是处理html页面的第一步,因为错误的编码必然带来后面处理的问题。这里我用python的正则表达
- 作者:Roland Smart原文链接:http://www.adaptivepath.com/ideas/newsletter/archi
- char、varchar、text和nchar、nvarchar、ntext的区别1、CHAR。CHAR存储定长数据很方便,CHAR字段上的
- 前言大家都知道golang的defer关键字,它可以在函数返回前执行一些操作,最常用的就是打开一个资源(例如一个文件、数据库连接等)时就用d
- 1. 确认已经安装了NT/2000和SQL Server的最新补丁程序,不用说大家应该已经安装好了,但是我觉得最好还是在这里提醒一
- 代码如下:<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001&quo
- V5.0之后,我们总结了一些得失。首先要说的是改版的动力。产品设计或产品升级的驱动力只有两个:用户需求和网站目标。之前的我们的多次改版,其驱
- [PHP] ; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而php.ini的设置更改可以反映出相当的变化,
- 笔者日积月累了许多精彩、实用的Web特效的制作,这些特效几乎都是比较常用的网页特效。现在我就把这些经过
- innerHTML 属性的使用非常流行,因为他提供了简单的方法完全替代一个 HTML 元素的内容。另外一个方法是使用 DOM Level 2