相机不够算法凑,拥有超级拍照能力的手机也离不开算法的加持。本文介绍的图像超分辨率项目可以帮你补齐相机镜头的短板。

华为P30发布会上展示的埃菲尔铁塔高清远距离照片。

今天,一位Reddit网友贴出了自己基于Keras的图像超分辨率项目,可以让照片放大后依然清晰。先来看一下效果。

放大数倍后,照片中的蝴蝶(蛾子?)依然没有失真,背上的绒毛清晰可见

作者表示,该项目旨在改善低分辨率图像的质量,使其焕然一新。使用该工具可以对图像进行超级放缩,还能很容易地在RDN和GAN上进行实验。

该项目包含不同残差密集网络的Keras实现,它们可用于高效的单图像超分辨率(ISR)。同时作者还提供了各种文档资料以帮助训练模型,包括如何使用对抗损失组件训练这些网络。

项目示例

这些示例使用的放大因子(upscalingfactor)为2,即像素数扩大两倍。大家可在sample_weights中查看生成示例图像的权重,它们存储在gitlfs上。如要下载这些权重,你需要先复制该repo,然后运行gitlfspull。

左图为原始的低分辨率图像,中间图为该网络的输出结果,右图为使用GIMPbicubicscaling得到的基线模型放大结果。

下面是不同方法作用于噪声图像的效果对比,这些方法分别是:使用bicubicscaling的基线模型、使用像素级内容损失函数训练的RDN网络,以及使用VGG19内容压缩数据集和损失函数进行重训练的RDN网络。该repo包含这些模型的权重。

Bicubicup-scaling(基线模型)的输出结果示例。

使用像素级内容损失函数训练的RDN网络的输出结果示例。

使用VGG内容和对抗损失组件训练的RDN网络的输出结果示例。

超分辨率项目有什么

前面展示的超分辨率效果都是根据该项目实现的不同模型做出来的。超分辨率希望根据已有的图像信息重构出缺失的图像细节,它通常借助卷积神经网络抽取图像信息,再通过转置卷积将这些信息扩展到希望获得的图像分辨率。

在这个项目中,作者新增了很多模块与特征,例如使用VGG与GAN实现真实的放大图像。该项目主要实现的是RDN与RRDN网络,且同时还提供了预训练权重和Colab教程。不论是训练还是推断,根据这些资料我们都可以快速上手。

此外,该项目目前已经可以发布到PyPI上了,因此安装也只需键入pip命令即可。

总而言之,整个项目实现了三个超分辨率网络,且采用了Keras版的VGG-19作为特征抽取模块。如下所示为三个超分辨率网络的相关研究:

ResidualDenseNetworkforImageSuper-Resolution(,arXiv:1802.08797)

ESRGAN:EnhancedSuper-ResolutionGenerativeAdversarialNetworks(,arXiv:1809.00219)

Photo-RealisticSingleImageSuper-ResolutionUsingaGenerativeAdversarialNetwork(SRGANS,,arXiv:1609.04802)

如果我们想要生成上面那样的高清图,该项目还提供了一系列的资源:

文档:

代码:

Colab推断代码:

Colab训练代码:

超分辨率项目怎么用

你可以选择两种方式安装图像超分辨率(ISR)包。

从PyPI中安装ISR(推荐):

pipinstallISR

从GitHub源安装ISR:

gitclone

预测

如果我们需要扩展低像素图像,简单两步就能借助ISR执行超分辨率。首先加载图像并做一定的预处理:

importnumpyasnpfromPILimportImageimg=('data/input/test_images/sample_')lr_img=(img)/255.lr_img=_dims(lr_img,axis=0)

加载模型并执行预测:

=RDN(arch_params={'C':6,'D':20,'G':64,'G0':64,'x':2})_weights('weights/rdn-C6-D20-G64-G064-x2_')sr_img=(lr_img)[0]sr_img=sr_(0,1)*255sr_img=(sr_img)(sr_img)

训练

如果需要使用你的数据集重新训练超分辨率模型,那我们也只需要改一改参数。如下首先创建模型:

_VGG19lr_train_patch_size=40layers_to_extract=[5,9]scale=2hr_train_patch_size=lr_train_patch_size*scalerrdn=RRDN(arch_params={'C':4,'D':3,'G':64,'G0':64,'T':10,'x':scale},patch_size=lr_train_patch_size)f_ext=Cut_VGG19(patch_size=hr_train_patch_size,layers_to_extract=layers_to_extract)discr=Discriminator(patch_size=hr_train_patch_size,kernel_size=3)

创建Trainer对象,并将训练的各种配置传递到该对象中:

_weights={'generator':0.0,'feat_extr':0.0833,'discriminator':0.01,}trainer=Trainer(generator=rrdn,discriminator=discr,feature_extractor=f_ext,lr_train_dir='low_res/training/images',hr_train_dir='high_res/training/images',lr_valid_dir='low_res/validation/images',hr_valid_dir='high_res/validation/images',loss_weights=loss_weights,dataname='image_dataset',logs_dir='./logs',weights_dir='./weights',weights_generator=None,weights_discriminator=None,n_validation=40,lr_decay_frequency=30,lr_decay_factor=0.5,T=0.01,)

开始训练:

(epochs=80,steps_per_epoch=500,batch_size=16,)

网络架构与超参数

实际上,如果我们需要重新训练,那么还需要了解具体的参数都表示什么。这一部分介绍了各超分辨率网络的架构与对应超参数。

RDN网络架构

RDN网络架构的主要参数如下:

D:残差密集块(RDB)数量

C:RDB内部堆叠的卷积层数量

G:RDB内部每一卷积层的特征图数量

RRDN网络架构

RRDN架构的主要参数如下:

T:残差密集块内的残差数量(RRDB)

D:每一RRDB内部的残差密集块(RDB)的数量

C:RDB内部堆叠的卷积层数量

G:RDB内部每一卷积层的特征图数量