超分辨方法-基于插值算法(最近邻,双线性,双三次)

Python实现双线性插值超分辨
Python实现最近邻插值超分辨
Pytohn实现双三次插值超分辨

  • 灰度图
import numpy as np
import math
import cv2

def double_linear(input_signal, zoom_multiples):
    '''
    双线性插值
    :param input_signal: 输入图像
    :param zoom_multiples: 放大倍数
    :return: 双线性插值后的图像
    '''
    input_signal_cp = np.copy(input_signal)   # 输入图像的副本

    input_row, input_col = input_signal_cp.shape # 输入图像的尺寸(行、列)

    # 输出图像的尺寸
    output_row = int(input_row * zoom_multiples)
    output_col = int(input_col * zoom_multiples)

    output_signal = np.zeros((output_row, output_col)) # 输出图片

    for i in range(output_row):
        for j in range(output_col):
            # 输出图片中坐标 (i,j)对应至输入图片中的最近的四个点点(x1,y1)(x2, y2),(x3, y3),(x4,y4)的均值
            temp_x = i / output_row * input_row
            temp_y = j / output_col * input_col

            x1 = int(temp_x)
            y1 = int(temp_y)

            x2 = x1
            y2 = y1 + 1

            x3 = x1 + 1
            y3 = y1

            x4 = x1 + 1
            y4 = y1 + 1

            u = temp_x - x1
            v = temp_y - y1

            # 防止越界
            if x4 >= input_row:
                x4 = input_row - 1
                x2 = x4
                x1 = x4 - 1
                x3 = x4 - 1
            if y4 >= input_col:
                y4 = input_col - 1
                y3 = y4
                y1 = y4 - 1
                y2 = y4 - 1

            # 插值
            output_signal[i, j] = (1-u)*(1-v)*int(input_signal_cp[x1, y1]) + (1-u)*v*int(input_signal_cp[x2, y2]) + u*(1-v)*int(input_signal_cp[x3, y3]) + u*v*int(input_signal_cp[x4, y4])
    return output_signal

# Read image
img = cv2.imread("source.jpg",0).astype(np.float)
out = double_linear(img,2).astype(np.uint8)
# Save result
cv2.imshow("result", out)
cv2.imwrite("out.jpg", out)
cv2.waitKey(0)
cv2.destroyAllWindows()

实验结果图

  • 彩色图

  • 不同的方式打开的图片颜色不同,什么问题?

  • 利用 img = Image.open(ImgPath) 打开的图片是PIL类型的,它自带resize函数。由于pytorch的顺序是(batch,c,h,w),所以需要进行PIL类型到numpy类型转换,tensorflow,numpy的顺序是(batch,h,w,c)。

超分辨方法-基于插值算法(最近邻,双线性,双三次)_第1张图片

from PIL import Image
import matplotlib.pyplot as plt
import cv2
import numpy as np
import math
def BiLinear_interpolation(img,dstH,dstW):
    scrH,scrW,_=img.shape
    img=np.pad(img,((0,1),(0,1),(0,0)),'constant')#np.padding。ndarray = numpy.pad(array, pad_width, mode, **kwargs)
    """
    array为要填补的数组
pad_width是在各维度的各个方向上想要填补的长度,如((1,2),(2,2)),表示在第一个维度上水平方向上padding=1,垂直方向上padding=2,
在第二个维度上水平方向上padding=2,垂直方向上padding=2。如果直接输入一个整数,则说明各个维度和各个方向所填补的长度都一样。
 mode为填补类型,即怎样去填补,有“constant”,“edge”等模式,如果为constant模式,就得指定填补的值,如果不指定,则默认填充0。 
    """
    retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
    for i in range(dstH):
        for j in range(dstW):
            scrx=(i+1)*(scrH/dstH)-1
            scry=(j+1)*(scrW/dstW)-1
            x=math.floor(scrx)#Math.floor() 返回小于或等于一个给定数字的最大整数。
            y=math.floor(scry)
            u=scrx-x
            v=scry-y
            retimg[i,j]=(1-u)*(1-v)*img[x,y]+u*(1-v)*img[x+1,y]+(1-u)*v*img[x,y+1]+u*v*img[x+1,y+1]
    return retimg
im_path='source2.jpg'
image=np.array(Image.open(im_path))
"""
利用 img = Image.open(ImgPath) 打开的图片是PIL类型的,它自带resize函数。
由于pytorch的顺序是(batch,c,h,w),所以需要进行PIL类型到numpy类型转换,tensorflow,numpy的顺序是(batch,h,w,c)
"""
# img = cv2.imread("source2.jpg",1)
# cv2.imshow("img",img)
cv2.imshow("image",image)
cv2.waitKey(0)
image2=BiLinear_interpolation(image,image.shape[0]*2,image.shape[1]*2)#参数1表示读入图像,参数2和参数3表示放大倍数是2倍
image2=Image.fromarray(image2.astype('uint8')).convert('RGB')#转换为RGB图像。
# cv2.imshow("image2",image2)
# cv2.waitKey(0)
image2.save('out2.png')

最近邻插值实现超分辨

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math

# 最近邻插值算法
# dstH为新图的高;dstW为新图的宽
def NN_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))#round就是四舍五入取整数
            scry=round(j*(scrW/dstW))
            retimg[i,j]=img[scrx,scry]
    return retimg

im_path='source2.jpg'
image=np.array(Image.open(im_path))

image1=NN_interpolation(image,image.shape[0]*2,image.shape[1]*2)
image1=Image.fromarray(image1.astype('uint8')).convert('RGB')
image1.save('NearInt.png')

可以看到最终的结果中含有锯齿状的边缘

你可能感兴趣的:(人脸超分辨)