图像超分辨,可看作由低分辨率图像生成高分辨率图像,如,由(64,64,3)的图像生成(256,256,3)的图像,新的图像更“大”,它和原图像有尺寸上的对应关系,它比原图像多出来的那些像素点的像素值,则是由原图像对应的一些点计算出来的。插值方法的不同,主要在于选择对应点的方法不同,是选择原图像中的1个点、4个点还是16个点?选的点越多,选的方法越好,插值结果越准确。
基于插值的方法包括最近邻插值法、双线性插值法、双三次插值法。图像灰度值定义在整数坐标中,通过放大缩小等尺寸变换可能产生非整数值,根据原图像中整数坐标的像素值推断新图像对应点的像素值即为插值变换。
最近邻插值法为插值生成的图像像素点赋值过程为:由目标图像的点计算出对应原图像的坐标,将距离这个坐标最近的整数点像素值直接赋给目标图像的点;若目标图像某点与原图像非整数坐标对应,则将求得的非整数坐标四舍五入后所得坐标的像素值赋予目标图像。若原图像高度、宽度分别为 w0、h0,原图像某点坐标为 (x0, y0),变换后图像高度、宽度为w1、h1,坐标为 (x1, y1),则两图像的坐标与像素值对应关系为
双线性插值法在待求像素四邻域像素的两个方向作线性插值,这种方法不直接使用邻域像素值,而是在待确定点内插一个值。若目标图像某点对应原图像的小数坐标为 (i + u, j + v) (其中 i、j 均为整数部分,u、v 为小数部分),则这个像素的值f(i + u, j + v) 可由原图像中坐标为 (i, j)、(i + 1, j)、(i, j + 1)、(i + 1, j + 1) 所对应的周围四个像素的值决定,如
可看出,这个坐标值为浮点数的虚拟坐标距离哪个点越近,获取这个点像素的权重就越高。
双三次插值法(Bicubic interpolation)由某个点周围 16 个点的像素值决定像素值,这 16 个点的
像素分别占多少权重则由权重函数(BICUBIC 函数)计算。
其中 s 表示权重 ,f 表示对应点的像素值,A、C赋予权重,同样是离对应点越近,权重越高。B是这16个点组成的矩阵。
重点是,img.resize那行代码选择不同的插值方法即可。(这是用的别人的,链接找不到了)
from PIL import Image
import os.path
import glob # 该方法返回所有匹配的文件路径列表(list)
Datadir = "./small/*.png"
savedir = "./BICUBIC/"
#输入(64,64,3)的LR图像
def convertpng(pngfile, outdir, width=256, height=256):
img = Image.open(pngfile)
new_img = img.resize((width, height), Image.BICUBIC)
new_img.save(os.path.join(savedir, os.path.basename(pngfile)))
#Image.NEAREST :最近邻
#Image.BILINEAR:双线性
#Image.BICUBIC :双三次
for pngfile in glob.glob(Datadir):
convertpng(pngfile, savedir)
下面的代码用于从原图获取低分辨率图像,可用于制作LR数据集。反过来,设置大于1的比例,就可实现基于插值的超分辨方法。(这是自己写的)
'''
Resize HR images to get LR images
'''
import os
from PIL import Image
indir = './DOTA3H/'
outdir = './DOTA3L/'
scale = 0.25
if not os.path.exists(outdir):
os.mkdir(outdir)
namelist = sorted(os.listdir(indir))
old_dir_n_name_list = [os.path.join(indir,_) for _ in namelist]
new_dir_n_name_list = [os.path.join(outdir, _) for _ in namelist]
for i,filepath in enumerate(old_dir_n_name_list):
im = Image.open(filepath)
(w,h) = im.size
new_w = int(w*0.25)
new_h = int(h*0.25)
print("Processing image",i+1,"From(w,h)",(w,h),"to(w,h)",(new_w,new_h),"remaining",len(old_dir_n_name_list)-(i+1))
out = im.resize((new_w,new_h),Image.BICUBIC)
out.save(new_dir_n_name_list[i])