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

放大2倍后:
在这里插入图片描述

显然比最近临插法效果好
缺点:当对相邻四个像素点采用双线性插值时,所得表面在邻域处是吻合的,但斜率不吻合。并且双线性灰度插值的平滑作用可能使得图像的细节产生退化,这种现象在进行图像放大时尤其明显。

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

放大2倍后:在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐