双线性插值

 假设源图像大小为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点进行插值,这就是所谓的双线性插值。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。

 

                                                        

 

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

 

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

 

 

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

 

 

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

 

 

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

 

 

或者用矩阵运算表示为

 

 

这种插值方法的结果通常不是线性的,线性插值的结果与插值的顺序无关。首先进

行 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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值