基于Python的图像双线性插值
- 双线性插值
对于曲面z=f(x,y),双线性插值是一种比较简单的插值方法。双线性插值需要已知曲面上的四个点,然后以此构建一张曲面片,得到双线性插值函数,进而可以根据该曲面片内部各个点处的横坐标和纵坐标来快速计算该点的竖坐标。具体的计算公式如下:
(1)
其中各个坐标如下图所示:
对于图像而言,相邻的四个像素,除了对角线上两个点外,其它点的距离都是1,因此上述公式中的各个点的横坐标和纵坐标可以归一化处理到区间[0,1],则上述插值公式就可以化简为:
(2)
此公式即为图像的双线性插值公式。
二、图像的双线性插值的Python实现
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
class ImageIntp( object ):
mFileName = []
mRatio = 0
def __init__( self, filename, ratio ):
self.mFileName = filename
self.mRatio = ratio
def getImageData( self ):
I = np.array( Image.open( self.mFileName ) );
return I
def biLinearIntpFun( self, ILu, ILb, IRu, IRb, x, y ):
z = x * ( ILb - ILu ) + y * ( IRu - ILu ) + x * y * ( ILu + IRb - IRu - ILb ) + ILu
return z
def ImageBiLinearIntp( self ):
I = self.getImageData()
r = self.mRatio
[ m, n ] = np.shape( I )
deltaR = 1
if( r >= 2 ):
deltaR = int(r )
elif( r > 0 and r < 2 ):
deltaR = 1
mr = int( m * r - deltaR )
nr = int( n * r - deltaR )
IR = np.zeros( (mr, nr) )
IR[mr-1][nr-1] = I[m-1][n-1]
if( r == 1 ):
IR = I
for i in range( mr ):
iyI = i / r
iI = int( iyI )
y = iyI - iI
for j in range( nr ):
jxI = j / r
jI = int( jxI )
x = jxI - jI
ILu = int(I[iI][jI])
ILb = int(I[iI+1][jI])
IRu = int(I[iI][jI+1])
IRb = int(I[iI+1][jI+1])
IR[i][j] = self.biLinearIntpFun( ILu, ILb, IRu, IRb, x, y )
return IR
def main():
obj = ImageIntp( 'lena.bmp', 0.5 )
IR = obj.ImageBiLinearIntp()
plt.figure( 'Intpolation1' )
plt.imshow( IR )
plt.axis( 'off' )
print( np.shape(IR) )
obj = ImageIntp( 'lena.bmp', 1.6 )
IR = obj.ImageBiLinearIntp()
plt.figure( 'Intpolation2' )
plt.imshow( IR )
plt.axis( 'off' )
print( np.shape(IR) )
obj = ImageIntp( 'lena.bmp', 2 )
IR = obj.ImageBiLinearIntp()
plt.figure( 'Intpolation3' )
plt.imshow( IR )
plt.axis( 'off' )
print( np.shape(IR) )
obj = ImageIntp( 'lena.bmp', 2.5 )
IR = obj.ImageBiLinearIntp()
plt.figure( 'Intpolation4' )
plt.imshow( IR )
plt.axis( 'off' )
print( np.shape(IR) )
if __name__ == '__main__':
main()
作者:YangYF