使用深度學習的單一圖像超分辨率
本示例演示如何訓練甚深超分辨率(vdsr)神經網絡,然後使用vdsr網絡從單個低分辨率圖像估計高分辨率圖像。
該示例演示了如何訓練vdsr網絡,並提供了預先培訓的vdsr網絡。如果您選擇培訓vdsr網絡,強烈建議使用具有cvida功能的nvidia™仇均,該網絡具有3.0或更高的計算能力。使用gpu需要並行計算工具箱™。
如果您不想下載培訓數據集或培訓網絡,則可以通過鍵入負載 ("traedvdsr-epoch-100 sc生殖器-scatemtors-23-mat“)來加載預訓練的vdsr網絡;在命令行。然後,直接轉到本例中load(‘trainedVDSR-Epoch-100-ScaleFactors-234.mat‘);
介紹
超分辨率是從低分辨率圖像創建高分辨率圖像的過程。本示例考慮單個圖像的超分辨率(sisr),其目標是從一個低分辨率圖像中恢復一個高分辨率圖像.ssis具具挑戰性,因為高頻圖像內容通常無法從低分辨率圖像中恢復。如果沒有高頻信息,高分辨率圖像的質量是有限的。此外,sisr是一個不恰當的問題,因為低分辨率圖像可以產生多個可能的高分辨率圖像。
提出了幾種執行sisr的技術,包括深度學習算法。本示例探討了一種用於sisr的深度學習算法,稱為甚深超分辨率(vdsr)[1]。
vdsr網絡
[1] .vdsr網絡學習低分辨率和高分辨率圖像之間的映射。
vdsr采用剩余學習策略,這意味著網絡學習估計剩余圖像。在超分辨率的背景下,殘差圖像是高分辨率參考圖像與使用雙次插值進行放大以匹配參考圖像大小的低分辨率圖像之間的區別。殘存圖像包含有關圖像的高頻細節的信息。
vdsr網絡從彩色圖像的亮度中檢測剩余圖像。圖像的亮度通道y通過紅色,Y
綠色和藍色像素值的線性組合表示每個像素的亮度。相反,圖像的兩個色度通道(cb和cr)是表示顏色差異信息的紅色,綠色和藍色像素值的不同線性組合 .vdsr只使用亮度通道進行訓練,因為人類對亮度變化比對顏色變化更敏感。
如果是高分辨率圖像的亮度和是使用雙雙值插值進行放大的低分辨率圖像的亮度,然後對vdsr網絡的輸入為而網絡學會了預測從培訓數據。
vdsr網絡學習估計剩余圖像後,可以通過將估計的剩余圖像添加到上采樣的低分辨率圖像,然後將圖像轉換回rgb顏色空間來重建高分辨率圖像。
比例因子將參考圖像的大小與低分辨率圖像的大小聯系起來。隨著比例因子的增加,由於低分辨率圖像丟失了更多有關高頻圖像內容的信息,sisr變得更加不恰當.vdsr通過使用大的接受場解決了這一問題。本示例使用規模增強對具有多個規模因子的vdsr網絡進行培訓。由於網絡可以利用較小比例因子的圖像上下文,因此在較大的比例因子下,比例增強可提高結果。此外,vdsr網絡還可以推廣接受具有跨尺度因素的圖像。
下載培訓和測試數據
下載iapr tc-12基準,其中包括20,000靜態自然圖像[2]。數據集包括人,動物,城市等的照片。您可以使用幫助器功能downloadIAPRTC12Data
,下載數據。數據文件的大小為~1 gb。
imagesDir = tempdir; url = ‘http://www-i6.informatik.rwth-aachen.de/imageclef/resources/iaprtc12.tgz‘ ; downloadIAPRTC12Data(URL,imagesDir);
本示例將使用iacr tc-12基準數據的一般部分來訓練網絡。加載映像clef訓練數據。所有圖像都是32位jpeg彩色圖像。
trainImagesDir = fullfile(imagesDir,‘iaprtc12‘,‘images‘,‘02‘); exts = { ‘.jpg‘,‘。bmp‘,‘。png‘ }; trainImages = imageDatastore(trainImagesDir,‘FileExtensions‘,exts );
列出訓練圖像的數量。
numel(trainImages.Files)
ans = 616
定義用於訓練的隨機修補程序提取數據存儲
使用隨機修補程序提取數據存儲將訓練數據提供給網絡。此數據存儲從包含網絡輸入和所需網絡響應的兩個映像數據存儲中提取隨機的相應修補程序。
在本例中,網絡輸入是使用雙次插值進行放大的低分辨率圖像。所需的網絡響應是剩余圖像。使用輔助功能createTrainingSet
訓練數據,例如將圖像轉換為ycbcr顏色空間,使用雙頻插值通過不同比例因子調整亮度(y)通道的大小,以及計算原始圖像和調整大小的圖像之間的差異。處理後的輸入映像作為。mat文件存儲在目錄upsampledDirName
的.mat
dirname中。計算出的殘差圖像作為.mat
mat文件存儲在目錄residualDirName
。
scaleFactors = [2 3 4]; [upsampledDirName,residualDirName] = createTrainingSet(trainImages,scaleFactors);
從輸入圖像文件的集合中創建一個名為upsampledImages
images的圖像數據存儲。從計算的剩余圖像文件集合中創建一個稱為residualImages
的圖像數據存儲。這兩個數據存儲都需要一個幫助器matRead
函數matread,才能從圖像文件中讀取圖像數據。
upsampledImages = imageDatastore(upsampledDirName,‘FileExtensions‘, ‘.MAT‘, ‘ReadFcn‘,@ matRead); residualImages = imageDatastore(residualDirName,‘FileExtensions‘, ‘.MAT‘, ‘ReadFcn‘,@ matRead);
創建一個imageDataAugmenter
指定數據擴充的參數。在培訓期間使用數據擴充來更改培訓數據,從而有效地增加可用培訓數據的數量。在這裏,加成指定90度的隨機旋轉和x方向的隨機反射。
augmenter = imageDataAugmenter(... ‘RandRotation‘,@()randi([0,1],1)* 90,... ‘RandXReflection‘,true);
從兩個圖像數據存儲中創建randomPatchExtractionDatastore
。指定41 x 41像素的修補程序大小(稍後在設置vdsr圖層時將解釋修補程序大小的選擇)。指定‘PatchesPerImage‘
,以便在訓練期間從每對圖像中提取64個隨機定位的補丁。指定一個小批處理大小為64。
miniBatchSize = 64; patchSize = [41 41]; patchds = randomPatchExtractionDatastore(upsampledImages,residualImages,patchSize,... 。 ‘PatchesPerImage‘,64,... ‘DataAugmentation‘ ,增強因子); patchds.MiniBatchSize = miniBatchSize;
randomPatchExtractionDatastore
時代的每個叠代中向網絡提供少量數據。在數據存儲上執行讀取操作以瀏覽數據。
inputBatch = read(patchds); 摘要(inputBatch)
變量: InputImage:64×1單元格 ResponseImage:64×1細胞
設置vdsr圖層
本示例使用深度學習工具箱™中的41個單獨圖層定義vdsr網絡,其中包括:
-
imageInputLayer
- 圖像輸入層 -
convolution2dLayer
-2d卷積層,適用於卷積神經網絡 -
reluLayer
- 校正線性單元(rlu)層 -
regressionLayer
- 神經網絡的回歸輸出層
第一層是imageInputLayer
對圖像補丁進行操作。斑塊大小是基於網絡接收場的,它是影響網絡中最上層的響應的空間圖像區域。理想情況下,網絡接收字段與圖像大小相同,以便可以看到圖像中的所有高級功能。在這種情況下,對於深度d網絡,接受場是( 2d +1) - (2d + 1)。由於vdsr是一個20層網絡,接受場和圖像貼片大小為41乘41. 圖像輸入層接受具有一個通道的圖像,因為vdsr僅使用亮度通道進行訓練。
networkDepth = 20; firstLayer = imageInputLayer([41 41 1],‘Name‘,‘InputLayer‘,‘Normalization‘,‘none‘);
圖像輸入圖層之後是一個二維卷積層,其中包含64個大小為3乘3的過濾器。將輸入零墊到每個卷積層,以便要素映射在每個卷積後保持與輸入相同的大小。他的方法[3]初始化隨機值的權重,以便神經元學習中存在不對稱。每個卷積層後面跟著一個relu層,它引入了網絡中的非線性。
convolutionLayer = convolution2dLayer(3,64,‘Padding‘,1,...... ‘Name‘,‘Conv1‘); convolutionLayer.Weights = sqrt(2 /(9 * 64))* randn(3,3,1,64); convolutionLayer.Bias = zeros(1,1,64);
指定一個llu圖層。
relLayer = reluLayer(‘Name‘,‘ReLU1‘);
中間層包含18個交替卷積和整流的線性單元層。每個卷積層包含64個大小為3比3乘64的過濾器,其中一個過濾器在64個通道的3乘3空間區域上運行。他的方法[3]初始化隨機值的權重。與以前一樣,每個卷積層後面都有一個relu層。
middleLayers = [convolutionLayer relLayer]; for layerNumber = 2:networkDepth-1 conv2dLayer = convolution2dLayer(3,64,... ‘Padding‘,[1 1],... ‘Name‘,[ ‘ Conv‘num2str(layerNumber)]); %他初始化 conv2dLayer.Weights = sqrt(2 /(9 * 64))* randn(3,3,64,64); conv2dLayer.Bias = zeros(1,1,64); relLayer = reluLayer(‘Name‘,[ ‘ ReLU‘num2str(layerNumber)]); middleLayers = [middleLayers conv2dLayer relLayer]; 結束
倒數第二層是一個卷積層,具有大小為3x3x64的單個濾波器,用於重建圖像。
conv2dLayer = convolution2dLayer(3,1,... ‘NumChannels‘,64,...... ‘填充‘,[1 1],... ‘名稱‘,[ ‘ Conv‘num2str(networkDepth)]); conv2dLayer.Weights = sqrt(2 /(9 * 64))* randn(3,3,64,1); conv2dLayer.Bias = zeros(1,1,1);
最後一層是回歸層,而不是rlu圖層。回歸層計算殘差圖像與網絡預測之間的均方誤差。
finalLayers = [conv2dLayer regressionLayer(‘Name‘,‘FinalRegressionLayer‘)];
連接所有圖層以形成vdsr網絡。
layers = [firstLayer middleLayers finalLayers];
或者,也可以使用此幫助器函數創建vdsr圖層。
layers = vdsrLayers();
指定培訓選項
利用隨機梯度下降和動量(sgdm)優化訓練網絡。使用功能指定sdgm的超參數設置。 trainingOptions
學習率最初設置為0.1,然後每20個時代下降10倍。火車100個世紀。
培訓深入的網絡是很耗時的。通過指定較高的學習率來加快培訓。但是,這可能會導致網絡的漸變無法控制地爆炸或增長,從而阻止網絡成功培訓。若要將漸變保持在有意義的範圍內,請通過將‘GradientThreshold‘
設置為0.01啟用漸變剪輯,並指定‘GradientThresholdMethod‘
以使用漸變的l2範數。
maxEpochs = 100; epochIntervals = 1; initLearningRate = 0.1; learningRateFactor = 0.1; l2reg = 0.0001; options = trainingOptions(‘sgdm‘,... ‘Momentum‘,0.9,... ‘InitialLearnRate‘,initLearningRate,... ‘LearnRateSchedule‘,‘piecewise‘,... ‘LearnRateDropPeriod‘,10,...... ‘ LearnRateDropFactor‘,learningRateFactor,...... ‘L2Regularization‘,l2reg,...... ‘MaxEpochs‘,maxEpochs,...... ‘MiniBatchSize‘,miniBatchSize,...... ‘GradientThresholdMethod‘,‘l2norm‘,...... ‘情節‘ ,‘訓練進步‘,... ‘GradientThreshold‘,0.01);
培訓網絡
在配置了訓練選項和隨機補丁提取數據存儲後,使用trainNetwork
網絡功能對vdsr網絡進行培訓。若要訓練網絡,請將下面代碼中的doTraining
參數設置為true
。高度推薦具有cvida™以上計算能力的nvidia™依照gpu進行培訓。
如果將下面代碼中的doTraining
參數保留為false
,則該示例返回一個預先訓練的vdsr網絡,該網絡已經過訓練,可以針對比例因子2,3和4進行超級解析。
Note: Training takes about 6 hours on an NVIDIA™ Titan X and can take even longer depending on your GPU hardware.
doTraining = false; 如果做訓練 modelDateTime = datestr(現在,‘dd-mmm-yyyy-HH-MM-SS‘); net = trainNetwork(patchds,layers,options); save([ ‘trainedVDSR- ‘modelDateTime‘ -Epoch- ‘num2str(maxEpochs * epochIntervals)‘ScaleFactors- ‘num2str(234)‘ 。 mat ‘ ],‘net‘,‘options‘); else load(‘trainedVDSR-Epoch-100-ScaleFactors-234.mat‘); 結束
使用vdsr網絡執行單個圖像超分辨率
要使用vdsr網絡執行單個圖像超分辨率(sisr),請按照本示例的其余步驟操作。該示例的其余部分演示如何:
-
從高分辨率參考圖像創建低分辨率圖像示例。
-
使用雙雙插值在低分辨率圖像上執行sisr,這是一種傳統的圖像處理解決方案,不依賴深度學習。
-
使用vdsr神經網絡在低分辨率圖像上執行sisr。
-
利用雙插值和vdsr對重建的高分辨率圖像進行目視比較。
-
通過量化圖像與高分辨率參考圖像的相似性來評價超分辨圖像的質量。
創建低分辨率圖像示例
創建一個低分辨率的圖像,將用於比較超分辨率的結果使用深度學習與結果的結果使用傳統的圖像處理技術,如雙雙插值。測試數據集testimages testImages
包含圖像處理工具箱™中附帶的21個未變形的圖像。將圖像加載到imageDatastore
中。
exts = { ‘.jpg‘,‘。png‘ }; fileNames = { ‘sherlock.jpg‘,‘car2.jpg‘,‘fabric.png‘,‘greens.jpg‘,‘hands1.jpg‘,‘kobi.png‘,... ‘lighthouse.png‘,‘micromarket .jpg‘,‘office_4.jpg‘,‘onion.png‘,‘pears.png‘,‘yellowlily.jpg‘,... ‘indiancorn.jpg‘,‘flamingos.jpg‘,‘sevilla.jpg‘,‘ llama.jpg‘,‘parkavenue.jpg‘,... ‘peacock.jpg‘,‘car1.jpg‘,‘strawberries.jpg‘,‘wagon.jpg‘ }; filePath = [fullfile(matlabroot,‘toolbox‘,‘images‘,‘imdata‘)filesep]; filePathNames = strcat(filePath,fileNames); testImages = imageDatastore(filePathNames,‘FileExtensions‘,exts);
將測試圖像顯示為蒙太奇。
蒙太奇(testImages)
選擇要用作超分辨率參考圖像的圖像之一。您可以選擇使用自己的高分辨率圖像作為參考圖像。
indx = 1; %要從測試圖像數據存儲區讀取的圖像索引 Ireference = readimage(testImages,indx); Ireference = im2double(Ireference); imshow(Ireference) 標題(‘高分辨率參考圖像‘)
使用縮放系數為0.25的大小調整來創建高分辨率參考圖像的低分辨率版本。 imresize
在縮小縮放過程中,圖像的高頻分量將丟失。
scaleFactor = 0.25; Ilowres = imresize(Ireference,scaleFactor,‘bicubic‘); imshow(Ilowres) 標題(‘低分辨率圖像‘)
使用雙參聯提高圖像分辨率
在沒有深度學習的情況下提高圖像分辨率的標準方法是使用雙插值。使用雙雙插值對低分辨率圖像進行升級,使生成的高分辨率圖像的大小與參考圖像的大小相同。
[nrows,ncols,np] = size(Ireference); Ibicubic = imresize(Ilowres,[nrows ncols],‘bicubic‘); imshow(Ibicubic) 標題(‘使用雙立方插值獲得的高分辨率圖像‘)
使用預先培訓的vdsr網絡提高圖像分辨率
回想一下,vdsr只使用圖像的亮度通道進行訓練,因為人類感知對亮度變化比對顏色變化更敏感。
使用函數將低分辨率圖像從rgb顏色空間轉換為亮度()和色度(和)通道。 rgb2ycbcr
Iy
Icb
Icr
Iycbcr = rgb2ycbcr(Ilowres); Iy = Iycbcr(:,:,1); Icb = Iycbcr(:,:,2); Icr = Iycbcr(:,:,3);
使用雙雙插值放大亮度和兩個色度通道。上采樣的色度通道icb _ Icb_bicubic
和Icr_bicubic
不需要進一步處理。
Iy_bicubic = imresize(Iy,[nrows ncols],‘bicubic‘); Icb_bicubic = imresize(Icb,[nrows ncols],‘bicubic‘); Icr_bicubic = imresize(Icr,[nrows ncols],‘bicubic‘);
通過訓練有素的vdsr網絡,通過放大的亮度組件,Iy_bicubic
亮度組件。觀察從最後一層(回歸層)激活 activations
網絡的輸出是所需的剩余圖像。
Iresidual =激活(net,Iy_bicubic,41); Iresidual = double(Iresidual); imshow(Iresidual,[]) 標題(來自VDSR的殘留圖像)
將剩余圖像添加到向上的亮度組件,以獲得高分辨率的vdsr亮度組件。
Isr = Iy_bicubic + Iresidual;
將高分辨率vdsr亮度組件與向上擴展的顏色組件連接在一起。使用函數將圖像轉換為rgb顏色空間。 ycbcr2rgb
其結果是使用vdsr的最終高分辨率彩色圖像。
Ivdsr = ycbcr2rgb(cat(3,Isr,Icb_bicubic,Icr_bicubic)); imshow(Ivdsr) 標題(‘使用VDSR獲得的高分辨率圖像‘)
視覺和定量比較
要更好地直觀地了解高分辨率圖像,請檢查每個圖像內的一個小區域。使用[ x y寬高度]格式的矢量指定感興趣的區域(roi)。 roi
這些元素定義左上角的x和y坐標,以及roi的寬度和高度。
roi = [320 30 480 400];
將高分辨率圖像裁剪到此roi,並以以太太奇的身份顯示結果。
蒙太奇({imcrop(Ibicubic,ROI),imcrop(Ivdsr,ROI)}) 標題(‘使用雙立方插值的高分辨率結果(左)與VDSR(右)‘);
vdsr圖像具有更清晰的細節和更清晰的邊緣。
使用圖像質量指標,使用對vdsr圖像的雙雙插值對高分辨率圖像進行定量比較。參考圖像是原始的高分辨率圖像Ireference
,,在準備樣品低分辨率圖像之前。
針對參考圖像測量每個圖像的峰值信噪比(psnr)。較大的pnsr值通常表示圖像質量更好。有關此指標的詳細信息,請參閱。 psnr
bicubicPSNR = psnr(Ibicubic,Ireference)
bicubicPSNR = 38.4747
vdsrPSNR = psnr(Ivdsr,Ireference)
vdsrPSNR = 39.2491
測量每個圖像的結構相似性指數(ssim).ssim評估圖像的三個特征(亮度,對比度和結構)對參考圖像的視覺影響.ssim值越接近1,測試圖像與參考圖像的一致就越好。有關此指標的詳細信息,請參閱。 ssim
bicubicSSIM = ssim(Ibicubic,Ireference)
bicubicSSIM = 0.9861
vdsrSSIM = ssim(Ivdsr,Ireference)
vdsrSSIM = 0.9875
利用自然性圖像質量評估器(niqe)測量感知圖像質量。較小的niqe分數表明有更好的感知質量。有關此指標的詳細信息,請參閱。 niqe
bicubicNIQE = niqe(Ibicubic)
bicubicNIQE = 5.1719
vdsrNIQE = niqe(Ivdsr)
vdsrNIQE = 4.7015
計算比例因子2,3和4的整個測試圖像集的平均psnr和ssim。這些是用於定義隨機修補Datastore
相同比例因子。為簡單起見,您可以使用幫助器函數超級superResolutionMetrics
計算平均指標。
superResolutionMetrics(凈,testImages,比例因子);
比例因子2的結果 Bicubic的平均PSNR = 31.809683 VDSR的平均PSNR = 31.926088 Bicubic的平均SSIM = 0.938194 VDSR的平均SSIM = 0.949278 比例因子3的結果 Bicubic的平均PSNR = 28.170441 VDSR的平均PSNR = 28.515179 Bicubic的平均SSIM = 0.884381 VDSR的平均SSIM = 0.895356 比例因子4的結果 Bicubic的平均PSNR = 27.010839 VDSR的平均PSNR = 27.849618 Bicubic的平均SSIM = 0.861604 VDSR的平均SSIM = 0.877360
對於每個比例因子,與雙次插值相比,vdsr具有更好的度量分數。
總結
本示例演示如何針對多個比例因子創建和訓練vdsr網絡,然後使用該網絡通過超分辨率提高圖像分辨率。以下是培訓網絡的步驟:
-
下載培訓數據。
-
將定義訓練數據提供給網絡的
RandomPatchExtractionDatastore
數據存儲。 -
定義vdsr網絡的層。
-
指定培訓選項。
-
使用
trainNetwork
功能培訓網絡。
在培訓vdsr網絡或加載預訓練的vdsr網絡後,該示例對低分辨率映像執行超分辨率。該實例將vdsr結果與超分辨率進行了比較,使用雙雙插值,不使用深度學習.vdsr在感知圖像質量和定量質量測量方面優於雙雙值插值。
引用
[1] “使用非常深的卷積網絡的精確圖像超分辨率.ieee 學報計算機視覺和模式識別會議。2016年,1646-1654頁。 ®
[2] “iepr tc-12基準:視覺信息系統的新評估資源。基於內容的圖像檢索的2006年語言資源論文集。意大利熱那亞第5卷,2006年5月,第10頁。
[3]“深入到整流器:在imagenet分類上超越人的水平表現.ieee 計算機視覺國際會議論文集,2015年,1026-1034頁。
關註公眾號: MATLAB基於模型的設計 (ID:xaxymaker) ,每天推送MATLAB學習最常見的問題,每天進步一點點,業精於勤荒於嬉。
打開微信掃一掃哦!
使用深度學習的單一圖像超分辨率