超分辨率重建技術(Super-Resolution)是指從觀測到的低分辨率圖像重建出相應的高分辨率圖像。
SR可分爲兩類:
1. 從多張低分辨率圖像重建出高分辨率圖像
2. 從單張低分辨率圖像重建出高分辨率圖像。
基於深度學習的SR,主要是基於單張低分辨率的重建方法,即Single Image Super-Resolution (SISR)html
Super-Resolution Convolutional Neural Network(PAMI 2016, 代碼)
該方法對於一個低分辨率圖像,先使用雙三次(bicubic)插值將其放大到目標大小,再經過三層卷積網絡作非線性映射,獲得的結果做爲高分辨率圖像輸出。python
Deeply-Recursive Convolutional Network for Image Super-Resolution(CVPR 2016, 代碼)
使用更多的卷積層增長網絡感覺野(41x41),同時爲了不過多網絡參數,該文章提出使用遞歸神經網絡(RNN)。
與SRCNN相似,該網絡分爲三個模塊,第一個是Embedding network,至關於特徵提取,第二個是Inference network, 至關於特徵的非線性變換,第三個是Reconstruction network,即從特徵圖像獲得最後的重建結果。其中的Inference network是一個遞歸網絡,即數據循環地經過該層屢次。將這個循環進行展開,就等效於使用同一組參數的多個串聯的卷積層,以下圖所示:git
其中的H1到HD是D個共享參數的卷積層。DRCN將每一層的卷積結果都經過同一個Reconstruction Net獲得一個重建結果,從而共獲得D個重建結果,再把它們加權平均獲得最終的輸出。另外,受到ResNet的啓發,DRCN經過skip connection將輸入圖像與Hd的輸出相加後再做爲Reconstruction Net的輸入,至關於使Inference Net去學習高分辨率圖像與低分辨率圖像的差,即恢復圖像的高頻部分。github
Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network(CVPR 2016, 代碼)算法
ESPCN的核心概念是亞像素卷積層(sub-pixel convolutional layer)。如上圖所示,網絡的輸入是原始低分辨率圖像,經過兩個卷積層之後,獲得的特徵圖像大小與輸入圖像同樣,可是特徵通道爲r^2 (r是圖像的目標放大倍數)。將每一個像素的r^2 個通道從新排列成一個r x r的區域,對應於高分辨率圖像中的一個r x r大小的子塊,從而大小爲r^2 x H x W的特徵圖像被從新排列成1 x rH x rW大小的高分辨率圖像。這個變換雖然被稱做sub-pixel convolution, 但實際上並無卷積操做。chrome
Real-Time Video Super-Resolution with Spatio-Temporal Networks and Motion Compensation(arxiv 2016)
上述幾種方法都只在單幅圖像上進行處理,而VESPCN提出使用視頻中的時間序列圖像進行高分辨率重建,而且能達到實時處理的效率要求。windows
Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network(arxiv, 21 Nov, 2016)
本文將生成式對抗網絡(GAN)用於SR問題。其出發點是傳統的方法通常處理的是較小的放大倍數,當圖像的放大倍數在4以上時,很容易使獲得的結果顯得過於平滑,而缺乏一些細節上的真實感。所以SRGAN使用GAN來生成圖像中的細節。網絡
github(tensorflow): https://github.com/zsdonghao/SRGANapp
github(tensorflow): https://github.com/buriburisuri/SRGANide
github(torch): https://github.com/junhocho/SRGAN
github(caffe): https://github.com/ShenghaiRong/caffe_srgan
github(tensorflow): https://github.com/brade31919/SRGAN-tensorflow
github(keras): https://github.com/titu1994/Super-Resolution-using-Generative-Adversarial-Networks
github(pytorch): ai-tor/PyTorch-SRGAN
Enhanced Deep Residual Networks for Single Image Super-Resolution, CVPRW2017
EDSR是NTIRE2017超分辨率挑戰賽上得到冠軍的方案。如論文中所說,EDSR最有意義的模型性能提高是去除掉了SRResNet多餘的模塊,從而能夠擴大模型的尺寸來提高結果質量。
github(torch): https://github.com/LimBee/NTIRE2017
github(tensorflow): https://github.com/jmiller656/EDSR-Tensorflow
github(pytorch): https://github.com/thstkdgus35/EDSR-PyTorch
EDSR的網絡結構以下:
標準化輸入head:卷積×1
body:resblock(卷積×2+relu)*16
tail:卷積×(n+1)
標準化輸出
其上採樣部分集成在tail的前n次卷積中,其中每次卷積將channels提高4倍,而後轉化爲放大2倍的feats(即將4個channels合併爲一個長寬加倍的channel),重複log(n,2)次。借用ESPCN(上文有講)的一張圖示意一下這種方法,順便一提,下面的WDSR上採樣層也是用的這個原理:
EDSR去掉了ResBlock中的bn層,僅在resblock輸出位置添加一個relu激活,源碼以下,
class ResBlock(nn.Module): def __init__( self, conv, n_feats, kernel_size, bias=True, bn=False, act=nn.ReLU(True), res_scale=1): super(ResBlock, self).__init__() m = [] for i in range(2): m.append(conv(n_feats, n_feats, kernel_size, bias=bias)) if bn: # EDSR 的觀點bn層對低抽象任務意義不大 m.append(nn.BatchNorm2d(n_feats)) if i == 0: m.append(act) # conv->conv->relu self.body = nn.Sequential(*m) self.res_scale = res_scale def forward(self, x): res = self.body(x).mul(self.res_scale) res += x return res
Wide Activation for Efficient and Accurate Image Super-Resolution,CVPRW2018
建構於超分辨 EDSR 算法,亦即 NTIRE 2018 年的冠軍模型,最主要的改進是在殘差模塊中 ReLU 激活函數前增大特徵圖。
github(pytorch):https://github.com/JiahuiYu/wdsr_ntire2018
一篇參考文章:https://blog.csdn.net/leviopku/article/details/85048846
WDSR_b網絡結構以下:
標準化輸入
head:卷積×1
body:block(卷積+relu+卷積×2)*16
tail:卷積×1
skip:卷積×1
標準化輸出
tail部分僅有一次卷積,實際放大思路同EDSR,不過是一次卷積獲得足夠的channels(3*n^2),一步重建爲3通道的圖像。
其結構中有幾個有意思的部分:
i. 其卷積層都外接了weight_norm層(w = g*v/||v||),聽說能夠必定程度緩解樣本不均衡問題,並有防止過擬合的功能(能夠看做一種正則化)。
ii. skip 結構其實是一個單層卷積(channels變化爲:3->3*n^2),從輸入圖片位置直接映射到tail的輸出,其輸出和tail輸出尺寸徹底一致,參照ResNet的方法合併,做爲網絡的輸出
iii. 其Block對一般的ResBlock有修改,首先和EDSR的ResBlock結構就不一致(EDSR的ResBlock也和經典的有必定出入),其次其channels安排不是常規的沙漏結構(輸入和輸出channels一致且大於中間的channel,可能目的是假定中間層提取抽象特徵),而是中間更大,爲了獲取更多的基礎特徵(做者認爲對於超像素重建這種低抽象任務須要更多的底層信息來反映特徵)。
class Block(nn.Module): def __init__( self, n_feats, kernel_size, wn, act=nn.ReLU(True), res_scale=1): super(Block, self).__init__() self.res_scale = res_scale body = [] expand = 6 linear = 0.8 body.append( wn(nn.Conv2d(n_feats, n_feats*expand, 1, padding=1//2))) # channels:64->64*6 body.append(act) body.append( # channels:64*6->64*0.8 wn(nn.Conv2d(n_feats*expand, int(n_feats*linear), 1, padding=1//2))) body.append( # channels:64*0.8->64 wn(nn.Conv2d(int(n_feats*linear), n_feats, kernel_size, padding=kernel_size//2))) self.body = nn.Sequential(*body) def forward(self, x): res = self.body(x) * self.res_scale res += x return res
Deep Back-Projection Networks For Super-Resolution, CVPR2018
github(caffe): https://github.com/alterzero/DBPN-caffe
github(pytorch): https://github.com/alterzero/DBPN-Pytorch
github:https://github.com/Hellcatzm/EDSR-PyTorch
其實就是網上開源的 EDSR 和 WDSR 兩個項目我合併了一下,有如下幾點注意:
本項目 fork 自網上開源項目,以 EDSR 算法爲基準,在原工程基礎上添加了 WDSR 算法,並部分添加了註釋,訓練方法在 /src/demo.sh 下記錄,注意不要去執行這個文件,該文件裏面記錄了工程的各類啓動方式,選擇想要執行的拷貝到命令行便可。
因爲項目涉及大量的多進程操做,使得本工程在 windows 下不能正常執行,請在 Linux 下測試本工程。
如需使用 WDSR ,把命令行指令相應位置的 EDSR 改寫爲 WDSR_a 或者 WDSR_b 便可(不區分大小寫)。
測試時咱們首先在 EDSR 項目目錄下新建 test 文件夾,存入低分辨率圖片,而後在 src 目錄下運行以下命令:
python main.py
--model 模型名稱(不區分大小寫)
--pre_train 已保存模型路徑
--test_only
--save_results
--data_test Demo
生成的圖片將保存在 experiment/results-Demo 文件夾下。
因爲兩個網絡咱們上面已經介紹了,對源碼感興趣的能夠再 src 的 model 下瀏覽各個模型的核心實現,其代碼由 model.__init__ 裏的通用部分加 model.模型名稱 裏的各個模型的分支實現組成,因爲 Pytorch 語法足夠簡潔且超分辨率重建網絡並不複雜(最討厭看目標檢測的代碼了,哈哈),因此再也不長篇講解源碼了,個人項目裏適當的給出了註釋,這裏貼個重建對比圖,超分辨率重建效果都是有一點糊,好像油畫同樣,且細節不足,這項技術遠遠沒有達到成熟。