双线性插值(Bilinear Interpolation)

双线性插值(Bilinear Interpolation)

    假设源图像大小为mxn,目标图像为axb。那么两幅图像的边长比分别为:m/a和n/b。注意,通常这个比例不是整数,编程存储的时候要用浮点型。目标图像的第(i,j)个像素点(i行j列)可以通过边长比对应回源图像。其对应坐标为(i*m/a,j*n/b)。显然,这个对应坐标一般来说不是整数,而非整数的坐标是无法在图像这种离散数据上使用的。双线性插值通过寻找距离这个对应坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)。

若图像为灰度图像,那么(i,j)点的灰度值的数学计算模型是:

                                                                      f(x,y)=b1+b2x+b3y+b4xy

如图,已知Q12,Q22,Q11,Q21,但是要插值的点为P点,这就要用双线性插值了,首先在x轴方向上,对R1和R2两个点进行插值,这个很简单,然后根据R1和R2对P点进行插值,这就是所谓的双线性插值。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。

                                                        clip_image001

        假如我们想得到未知函数 f 在点 P = (xy) 的值,假设我们已知函数 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四个点的值。

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

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

这样就得到所要的结果 f(xy),

如果选择一个坐标系统使得 f 的四个已知点坐标分别为 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那么插值公式就可以化简为

f(x,y) \approx f(0,0) \, (1-x)(1-y) + f(1,0) \, x(1-y) + f(0,1) \, (1-x)y + f(1,1) xy.

或者用矩阵运算表示为

f(x,y) \approx \begin{bmatrix}1-x & x \end{bmatrix} \begin{bmatrix}f(0,0) & f(0,1) \\f(1,0) & f(1,1) \end{bmatrix} \begin{bmatrix}1-y \\y \end{bmatrix}

这种插值方法的结果通常不是线性的,线性插值的结果与插值的顺序无关。首先进行 y 方向的插值,然后进行 x 方向的插值,所得到的结果是一样的。

python代码实现

#!/bin/python
import numpy as np
from scipy.misc import imread, imshow
from scipy import ndimage
 
def GetBilinearPixel(imArr, posX, posY):
	out = []
 
	#Get integer and fractional parts of numbers
	modXi = int(posX)
	modYi = int(posY)
	modXf = posX - modXi
	modYf = posY - modYi
	modXiPlusOneLim = min(modXi+1,imArr.shape[1]-1)
	modYiPlusOneLim = min(modYi+1,imArr.shape[0]-1)
 
	#Get pixels in four corners
	for chan in range(imArr.shape[2]):
		bl = imArr[modYi, modXi, chan]
		br = imArr[modYi, modXiPlusOneLim, chan]
		tl = imArr[modYiPlusOneLim, modXi, chan]
		tr = imArr[modYiPlusOneLim, modXiPlusOneLim, chan]
 
		#Calculate interpolation
		b = modXf * br + (1. - modXf) * bl
		t = modXf * tr + (1. - modXf) * tl
		pxf = modYf * t + (1. - modYf) * b
		out.append(int(pxf+0.5))
 
	return out
 
if __name__=="__main__":
 
	im = imread("test.jpg", mode="RGB")
	enlargedShape = list(map(int, [im.shape[0]*1.6, im.shape[1]*1.6, im.shape[2]]))
	enlargedImg = np.empty(enlargedShape, dtype=np.uint8)
	rowScale = float(im.shape[0]) / float(enlargedImg.shape[0])
	colScale = float(im.shape[1]) / float(enlargedImg.shape[1])
 
	for r in range(enlargedImg.shape[0]):
		for c in range(enlargedImg.shape[1]):
			orir = r * rowScale #Find position in original image
			oric = c * colScale
			enlargedImg[r, c] = GetBilinearPixel(im, oric, orir)
 
	imshow(enlargedImg)
 

参考:

https://www.cnblogs.com/kk17/p/9989984.html

  • 7
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Bilinear interpolation双线性插值)是一种用于在离散数据点之间进行插值的方法。它通过在两个方向上进行线性插值来估计未知点的值。这种插值方法常用于图像处理和计算机图形学中。 双线性插值的原理是基于两个相邻的数据点之间的线性插值。首先,根据给定的坐标找到四个最近的数据点,然后在水平和垂直方向上进行线性插值,以获得未知点的值。 以下是一个使用双线性插值的示例代码[^1]: ```python import numpy as np def bilinear_interpolation(x, y, points): x1, y1 = points[0] x2, y2 = points[1] q11 = points[2] q12 = points[3] q21 = points[4] q22 = points[5] f = 1 / ((x2 - x1) * (y2 - y1)) value = f * ( q11 * (x2 - x) * (y2 - y) + q21 * (x - x1) * (y2 - y) + q12 * (x2 - x) * (y - y1) + q22 * (x - x1) * (y - y1) ) return value # 示例数据点 points = np.array([ [0, 0, 1, 3, 2, 4], [0, 1, 6, 8, 7, 9] ]) # 插值点坐标 x = 0.5 y = 0.5 # 进行双线性插值 result = bilinear_interpolation(x, y, points) print("Interpolated value:", result) ``` 这段代码中,我们定义了一个`bilinear_interpolation`函数,它接受插值点的坐标和四个最近的数据点的值作为输入。然后,根据双线性插值的公式计算出插值点的值,并返回结果。 在上面的示例中,我们使用了一个简单的二维数组作为示例数据点,然后对坐标为(0.5, 0.5)的点进行双线性插值。最后,输出插值点的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值