沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

機器之心發表於2019-03-27
華為剛剛釋出的 P30「望遠鏡」手機能在幾十米外拍到艾菲爾上的人名,確實令人佩服,但其售價也是令人望而生畏。那麼,不買華為手機、高階單反就拍不到充滿細節的高清照片了嗎?

相機不夠演算法湊,擁有超級拍照能力的手機也離不開演算法的加持。本文介紹的影象超解析度專案可以幫你補齊相機鏡頭的短板。

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

華為 P30 釋出會上展示的艾菲爾鐵塔高清遠距離照片。

今天,一位 Reddit 網友貼出了自己基於 Keras 的影象超解析度專案,可以讓照片放大後依然清晰。先來看一下效果。

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

放大數倍後,照片中的蝴蝶(蛾子?)依然沒有失真,背上的絨毛清晰可見。

作者表示,該專案旨在改善低解析度影象的質量,使其煥然一新。使用該工具可以對影象進行超級放縮,還能很容易地在 RDN 和 GAN上進行實驗。

該專案包含不同殘差密集網路的 Keras 實現,它們可用於高效的單影象超解析度(ISR)。同時作者還提供了各種文件資料以幫助訓練模型,包括如何使用對抗損失元件訓練這些網路。

專案示例

這些示例使用的放大因子(upscaling factor)為 2,即畫素數擴大兩倍。大家可在 sample_weights 中檢視生成示例影象的權重,它們儲存在 git lfs 上。如要下載這些權重,你需要先複製該 repo,然後執行 git lfs pull。

左圖為原始的低解析度影象,中間圖為該網路的輸出結果,右圖為使用 GIMP bicubic scaling 得到的基線模型放大結果。

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

下面是不同方法作用於噪聲影象的效果對比,這些方法分別是:使用 bicubic scaling 的基線模型、使用畫素級內容損失函式訓練的 RDN 網路,以及使用 VGG19 內容壓縮資料集和損失函式進行重訓練的 RDN 網路。該 repo 包含這些模型的權重

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

Bicubic up-scaling(基線模型)的輸出結果示例。

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

使用畫素級內容損失函式訓練的 RDN 網路的輸出結果示例。

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

使用 VGG 內容和對抗損失元件訓練的 RDN 網路的輸出結果示例。

超解析度專案有什麼

前面展示的超解析度效果都是根據該專案實現的不同模型做出來的。超解析度希望根據已有的影象資訊重構出缺失的影象細節,它通常藉助卷積神經網路抽取影象資訊,再通過轉置卷積將這些資訊擴充套件到希望獲得的影象解析度。

在這個專案中,作者新增了很多模組與特徵,例如使用 VGG 與 GAN 實現真實的放大影象。該專案主要實現的是 RDN 與 RRDN 網路,且同時還提供了預訓練權重和 Colab 教程。不論是訓練還是推斷,根據這些資料我們都可以快速上手。

此外,該專案目前已經可以釋出到 PyPI 上了,因此安裝也只需鍵入 pip 命令即可。

總而言之,整個專案實現了三個超解析度網路,且採用了 Keras 版的 VGG-19 作為特徵抽取模組。如下所示為三個超解析度網路的相關研究:

  • Residual Dense Network for Image Super-Resolution(Zhang et al. 2018, arXiv:1802.08797)

  • ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks(Wang et al. 2018, arXiv:1809.00219)

  • Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network(SRGANS, Ledig et al. 2017, arXiv:1609.04802)

如果我們想要生成上面那樣的高清圖,該專案還提供了一系列的資源:

  • 文件:https://idealo.github.io/image-super-resolution/

  • 程式碼:https://github.com/idealo/image-super-resolution/

  • Colab 推斷程式碼:https://colab.research.google.com/github/idealo/image-super-resolution/blob/master/notebooks/ISR_Prediction_Tutorial.ipynb

  • Colab 訓練程式碼:https://colab.research.google.com/github/idealo/image-super-resolution/blob/master/notebooks/ISR_Traininig_Tutorial.ipynb

超解析度專案怎麼用

你可以選擇兩種方式安裝影象超解析度(ISR)包。

從 PyPI 中安裝 ISR(推薦):

pip install ISR

從 GitHub 源安裝 ISR:

git clone https://github.com/idealo/image-super-resolution

cd image-super-resolution

python setup.py install

預測

如果我們需要擴充套件低畫素影象,簡單兩步就能借助 ISR 執行超解析度。首先載入影象並做一定的預處理:

import numpy as npfrom PIL import Image

img = Image.open('data/input/test_images/sample_image.jpg')
lr_img = np.array(img)/255.
lr_img = np.expand_dims(lr_img, axis=0)

載入模型並執行預測:

from ISR.models import RDN

rdn = RDN(arch_params={'C':6, 'D':20, 'G':64, 'G0':64, 'x':2})
rdn.model.load_weights('weights/rdn-C6-D20-G64-G064-x2_enhanced-e219.hdf5')

sr_img = rdn.model.predict(lr_img)[0]
sr_img = sr_img.clip(0, 1) * 255
sr_img = np.uint8(sr_img)
Image.fromarray(sr_img)

訓練

如果需要使用你的資料集重新訓練超解析度模型,那我們也只需要改一改引數。如下首先建立模型:

from ISR.models import RRDN
from ISR.models import Discriminator
from ISR.models import Cut_VGG19

lr_train_patch_size = 40
layers_to_extract = [5, 9]
scale = 2
hr_train_patch_size = lr_train_patch_size * scale

rrdn  = 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 物件,並將訓練的各種配置傳遞到該物件中:

from ISR.train import Trainer

loss_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,
)

開始訓練:

trainer.train(
    epochs=80,
    steps_per_epoch=500,
    batch_size=16,
)

網路架構與超引數

實際上,如果我們需要重新訓練,那麼還需要了解具體的引數都表示什麼。這一部分介紹了各超解析度網路的架構與對應超引數

RDN 網路架構

RDN 網路架構的主要引數如下:

  • D:殘差密集塊(RDB)數量

  • C:RDB 內部堆疊的卷積層數量

  • G:RDB 內部每一卷積層的特徵圖數量

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

圖源:https://arxiv.org/abs/1802.08797

RRDN 網路架構

RRDN 架構的主要引數如下:

  • T:殘差密集塊內的殘差數量(RRDB)

  • D:每一 RRDB 內部的殘差密集塊(RDB)的數量

  • C:RDB 內部堆疊的卷積層數量

  • G:RDB 內部每一卷積層的特徵圖數量

沒錢買華為P30?這個影象超解析度專案幫你「拍」出高清照片

圖源:https://arxiv.org/abs/1809.00219

相關文章