- 雙線性插值
對於曲面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