双线性插值法(bilinearinterpolation)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
双线性插值法(bilinearinterpolation)
前⾯讲解了最近邻插值法缩放图像以及不⾜之处,本篇介绍另外⼀种插值法,介绍双线性插值法之前先介绍线性插值。
1. 线性插值
线性插值是指插值函数为⼀次多项式的插值⽅式,其在插值节点上的插值误差为零。
线性插值可以⽤来近似代替原函数,也可以⽤来计算得到查表过程中表中没有的数值。
如图所⽰现在已知y=f(x)的两个点坐标分别是(x0,y0),(x1,y1),现在在区间(x0,x1)内给定任意x,如何求y,线性插值法采⽤图中红点的y值代替f(x)的y值。
假设x处的直线上的红点坐标为(x,Y),那么Y约等于y。
根据图可以得到公式:
⽤y0,y1表⽰得到
公式很好记,将分式看做权重系数。
2. 双线性插值法
双线性插值法也叫双线性内插,其核⼼思想是在两个⽅向分别进⾏⼀次线性插值。
双线性插值作为数值分析中的⼀种插值算法,⼴泛应⽤在信号处理,数字图像和视频处理等⽅⾯。
如坐标图所⽰,⽤横纵坐标代表图像像素的位置,f(x,y)代表该像素点(x,y)的彩⾊值或灰度值。
将图像放⼤或缩⼩,⽬的像素dst对应的原像素src中的坐标转换公式如下,公式很好理解,可参考上⼀章最近邻插值法。
srcX=dstX*(srcWidth/dstWidth)
srcY=dstY*(srcHeight/dstHeight)
上式中,dstX与dstY为⽬标图像的某个像素的横纵坐标,dstWidth与dstHeight为⽬标图像的长与宽;srcWidth与srcHeight为原图像的宽度与⾼度。
srcX,srcY为⽬标图像在该点(dstX,dstY)对应的原图像的坐标。
现在假设⽬标图像的像素点(x’,y’)映射到原图像中是(x,y),也就是图中的P点。
设Q11 = (x1, y1)、Q12 = (x1, y2)、Q21 = (x2, y1) 、
Q22 = (x2, y2),图中Q11,Q12,Q21,Q22分别为距离P点的最近的四个点。
分别在X⽅向进⾏两次插值,最后在y⽅向进⾏插值即可得到⽬标图像的像素值。
公式如下:
先计算X⽅向(也可以先计算Y⽅向,再计算X⽅向)的线性插值:
再在y⽅向进⾏线性插值得到f(P):
经过公式的进⼀步化简可以得到:
由于是最近的点,所以Q的四个点的坐标之间相差1,故进⼀步化简为:
现假设x=i+u,y=j+v,i,j为整数,u,v为⼩数。
得到下式:
下⾯为本⼈⾃⼰设计的例⼦与具体计算过程:
将图像放⼤两倍(对像素数扩⼤2倍),以?处的像素为例:
右边图中问号的坐标为(5,4),映射到原图像的像素点的坐标为
srcX=dstX*(srcWidth/dstWidth)=5*(4/8)=2.5
srcY=dstY*(srcHeight/dstHeight)=4*(4/8)=2
(srcX,srcY)=(2+0.5,2+0),u=0.5,v=0,映射的src坐标及对应的最近的四个Q点下如图所⽰。
若x=i+u,y=j+v。
则可以得到红⾊框的像素及其周围四个Q点(i,j)、(i+1,j)、(i,j+1)、(i+1,j+1),即可以得到?处的像素值。
每个像素点的RGB对应如下:
204,255,153 153,255,153 102,255,153 0,255,153
204,255,102 153,255,102 102,255,102 0,255,0
204,255,51 153,255,51 102,255,51 51,204,51
204,204,0 153,204,0 102,153,0 0,153,0
Q11(2,2),Q21(2,3),Q12(3,2),Q22(3,3),P(2.5,2)
采⽤双线性插值法得到红⾊框处的像素值:
R=0.5*102+0.5*51=51+25.5=76.5
G=0.5*255+0.5*204=127.5+102=229.5
B=0.5*51+0.5*51=25.5+25.5=51
由于颜⾊表⽰范围为0-255整数,R可以⽤127代替或128代替,B也是。
所以问号处的颜⾊应该为:
然后以同样的⽅式计算得到所有的像素值,放⼤后的图像对⽐如下:
当出现i或j为边界坐标时,会出现(i+1,j)、(i,j+1)、(i+1,j+1)的点在实际的图中不存在,此时可以⽤(i,j)、(i-1,j)、(i,j-1)、(i-1,j-1)。
如果srcX与srcY是整数,则其中⼀个点是(i,j),剩余的3个点其实⽆所谓,因为u,v为0。
f(p)=f(i,j)
3. 代码实现
python实现:
from matplotlib import pyplot as plt
import numpy as np
def bilinear_interpolation(srcimage_vector,dstwidthtimes ,dstheighttimes ):
print("原始图像",srcimage_vector)
srcHeight=srcimage_vector.shape[0]
srcWidth=srcimage_vector.shape[1]
print("srcHeight",srcHeight)
print("srcWidth",srcWidth)
dstWidth, dstHeight=int(dstwidthtimes*srcWidth),int(dstheighttimes*srcHeight)
# 定义⼀个三维矩阵存储⽬标图像,每个像素由RGB三种颜⾊组成,shape接受⼀个元组,可以创建多维矩阵
dstVector = np.zeros(shape=(dstHeight, dstWidth, 3), dtype=int) # 默认是float64
# 遍历⽬标图像的每⼀个像素
for dstY in range(0,dstHeight):
for dstX in range(0,dstWidth):
Q = [(0, 0)] * 4 # Q11=Q12=Q21=Q22=0
Qdict = {}
# 坐标换算
dstX_srcX = dstX * (srcWidth / dstWidth) # python中/表⽰除法,//表⽰整除
dstY_srcY = dstY * (srcHeight / dstHeight)
u = round(dstX_srcX % 1, 2)
v = round(dstY_srcY % 1, 2)
if int(dstX_srcX)==srcWidth-1:
positionX = [int(dstX_srcX)-1, int(dstX_srcX)] # 左右范围
else:
positionX=[int(dstX_srcX),int(dstX_srcX)+1]#左右范围
if int(dstY_srcY)==srcHeight-1:
positionY = [int(dstY_srcY)-1, int(dstY_srcY)] # 上下范围
else:
positionY = [int(dstY_srcY), int(dstY_srcY) + 1] #上下范围
k=0
for m in range(0, 2): # 得到Q的四个点坐标,分别是Q11,Q12,Q21,Q22
for n in range(0, 2):
Q[k] = (positionX[m], positionY[n])
Qdict[Q[k]] = srcimage_vector[positionY[n], positionX[m]]
k = k + 1
# 通过四个点计算得到dst的像素值
dstVector[dstY][dstX] = Qdict[Q[0]] * (1 - u) * (1 - v) + Qdict[Q[1]] * (1 - u) * (v) + Qdict[Q[2]] * (u) * (
1 - v) + Qdict[Q[3]] * (u) * (v)
print(dstVector)
ax = plt.gca() # 获取到当前坐标轴信息
ax.xaxis.set_ticks_position('top') # 将X坐标轴移到上⾯
plt.imshow(dstVector) # 显⽰数组
plt.show()
plt.imsave('shaungxianxing.jpg', dstVector.astype(np.uint8)) # matplotlib保存图像的时候,只接受浮点数或者unit8的整数类型if __name__=="__main__":
# imagePath = r'songshu.jpg'
imagePath = r'cup.jpg'
# imagePath = r'aoyunwuhuan.jpg'
image_vector = plt.imread(imagePath)
# dstwidth,dstheight⽤倍数表⽰,表⽰是src图像的多少倍
# dstwidth, dstheight=1.5,1.5
dstwidth, dstheight=0.2,0.2
bilinear_interpolation(image_vector,dstwidth,dstheight)
C++实现:后⾯补充。
4.效果
⾃⼰制作的奥运五环
原图
双线性插值法放⼤2倍后的图像
邻近法放⼤2倍后的图像
⽹上找的松⿏:
原图
放⼤2倍后
缩⼩0.2倍后
⼿机拍的图原图
缩⼩0.2倍
结论:通过图可以看出,双线性插值法,锯齿状⽐邻近法效果好多了,但是也会伴随着图⽚的变模糊。
5.存在问题及改进:
关于中⼼问题,后⾯补充。