1、最近邻插法`
#最近邻插值法
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math
def interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for i in range(dstH-1):
for j in range(dstW-1):
scrx=round(i*(scrH/dstH))#四舍五入
scry=round(j*(scrW/dstW))
retimg[i,j]=img[scrx,scry]
return retimg
im=Image.open('testImg.jpg') #读取图片
im_array=np.array(im) #将图片信息转化为数组保存
image1=interpolation(im_array,int(im_array.shape[0]*2),int(im_array.shape[1]*2))
image1=Image.fromarray(image1.astype('uint8')).convert('RGB')
image1.show()
原图像:
放大2倍后:
缺点:四舍五入选取最接近的整数,这样的做法会导致像素的变化不连续,在新图中会产生锯齿。
2、双线性插值法
#双线性插值法
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import math
def bilinear(img,dstH,dstW):
src_H,src_W,_=img.shape
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for dstX in range(dstH-1):
for dstY in range(dstW-1):
#源图像和目标图像几何中心的对齐
srcX=(dstX+0.5)*(src_W/dstW)-0.5
srcY=(dstY+0.5)*(src_H/dstH)-0.5
#四个点坐标
x1=round(srcX - 0.5)
x2=round(srcX+0.5)
y1=round(srcY-0.5)
y2=round(srcY+0.5)
#X轴方向线插
fy1=(x2-srcX)*img[int(x1),int(y1)]+(srcX-x1)*img[int(x2),int(y1)]
fy2=(x2-srcX)*img[int(x1),int(y2)]+(srcX-x1)*img[int(x2),int(y2)]
#Y轴方向线插
retimg[dstX,dstY]=(y2-srcY)*fy1+(srcY-y1)*fy2
return retimg
im=Image.open('testImg.jpg')
im_array = np.array(im)
image1 = bilinear(im_array, im_array.shape[0] * 2, im_array.shape[1] * 2)
image1 = Image.fromarray(image1.astype('uint8')).convert('RGB')
image1.show()
显然比最近临插法效果好
缺点:当对相邻四个像素点采用双线性插值时,所得表面在邻域处是吻合的,但斜率不吻合。并且双线性灰度插值的平滑作用可能使得图像的细节产生退化,这种现象在进行图像放大时尤其明显。
3、双三次插值算法
from PIL import Image
import numpy as np
import math
# 产生16个像素点不同的权重
def BiBubic(x):
x=abs(x)
if x<=1:
return 1-2*(x**2)+(x**3)
elif x<2:
return 4-8*x+5*(x**2)-(x**3)
else:
return 0
# 双三次插值算法
def BiCubic_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
#img=np.pad(img,((1,3),(1,3),(0,0)),'constant')
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for i in range(dstH):
for j in range(dstW):
scrx=i*(scrH/dstH)
scry=j*(scrW/dstW)
x=math.floor(scrx)
y=math.floor(scry)
u=scrx-x
v=scry-y
tmp=0
for ii in range(-1,2):
for jj in range(-1,2):
if x+ii<0 or y+jj<0 or x+ii>=scrH or y+jj>=scrW:
continue
tmp+=img[x+ii,y+jj]*BiBubic(ii-u)*BiBubic(jj-v)
retimg[i,j]=np.clip(tmp,0,255)
return retimg
im_path='testImg.jpg'
image=np.array(Image.open(im_path))
image2=BiCubic_interpolation(image,image.shape[0]*2,image.shape[1]*2)
image2=Image.fromarray(image2.astype('uint8')).convert('RGB')
image2.show()