使用深度学习提高图像分辨率
这个例子展示了如何使用非常深的超分辨率(VDSR)神经网络从低分辨率图像创建高分辨率图像。
超分辨率是指从低分辨率图像创建高分辨率图像的过程。本例考虑的是单幅图像超分辨率(SISR),其目标是从一张低分辨率图像中恢复一张高分辨率图像。SISR具有挑战性,因为高频图像内容通常无法从低分辨率图像中恢复。没有高频信息,高分辨率图像的质量是有限的。此外,SISR是一个不适定问题,因为一个低分辨率的图像可以产生几个可能的高分辨率图像。
已经提出了包括深度学习算法在内的几种技术来执行SISR。这个例子探索了一种用于SISR的深度学习算法,称为超深分辨率(VDSR) [1].
VDSR网络
VDSR是一种卷积神经网络架构,旨在执行单幅图像的超分辨率[1].VDSR网络学习低分辨率和高分辨率图像之间的映射。这种映射是可能的,因为低分辨率和高分辨率图像具有相似的图像内容,主要在高频细节上有所不同。
VDSR采用了残差学习策略,这意味着网络学习估计残差图像。在超分辨率的背景下,残差图像是高分辨率参考图像和低分辨率图像之间的差异,低分辨率图像使用双三次插值来匹配参考图像的大小。残差图像包含关于图像高频细节的信息。
VDSR网络根据彩色图像的亮度检测残差图像。图像的亮度通道,Y
,表示每个像素的亮度,通过红、绿、蓝像素值的线性组合。相比之下,图像的两个色度通道,Cb而且Cr,是表示色差信息的红色、绿色和蓝色像素值的不同线性组合。VDSR只使用亮度通道进行训练,因为人类的感知对亮度变化比对颜色变化更敏感。
如果 高分辨率图像的亮度和 亮度是否是使用双三次插值放大的低分辨率图像,那么VDSR网络的输入是 网络学会了预测 从训练数据中。
在VDSR网络学会估计残差图像后,您可以通过将估计的残差图像添加到上采样的低分辨率图像中,然后将图像转换回RGB颜色空间来重建高分辨率图像。
比例因子将参考图像的大小与低分辨率图像的大小联系起来。随着比例因子的增加,由于低分辨率图像丢失了更多关于高频图像内容的信息,因此SISR变得更加病态。VDSR通过使用一个大的接受野来解决这个问题。本例使用缩放增强来训练具有多个缩放因子的VDSR网络。由于网络可以利用较小尺度因子的图像上下文,因此尺度增强可以改善较大尺度因子下的结果。此外,VDSR网络可以泛化到接受具有非整数比例因子的图像。
下载培训和测试数据
下载IAPR TC-12基准,其中包括2万张静止自然图像[2].数据集包括人物、动物、城市等的照片。数据文件的大小为~1.8 GB。如果你不想下载训练数据集,那么你可以通过输入加载预训练的VDSR网络负载(“trainedVDSRNet.mat”);
在命令行。然后,直接去使用VDSR网络实现单幅图像超分辨率节。
使用helper函数,downloadIAPRTC12Data
下载资料。该函数作为支持文件附加到示例中。万博1manbetx指定dataDir
作为数据的期望位置。
dataDir =tempdir;downloadIAPRTC12Data (dataDir);
本例将使用IAPR TC-12基准数据的一小部分来训练网络。加载imageCLEF训练数据。所有图像均为32位JPEG彩色图像。
trainImagesDir = fullfile(dataDir,“iaprtc12”,“图片”,“2”);Exts = [“jpg”,“bmp格式”,“使用”];pristineImages = imageDatastore(trainImagesDir,FileExtensions=exts);
列出训练图像的数量。
元素个数(pristineImages.Files)
Ans = 616
准备培训数据
为了创建一个训练数据集,生成由上采样图像和相应的残差图像组成的图像对。
上采样图像以MAT文件的形式存储在磁盘上的目录中upsampledDirName
.表示网络响应的计算残差图像作为MAT文件存储在磁盘上的目录中residualDirName
.MAT文件以数据类型存储双
为了训练网络时更精确。
upsampledDirName = trainImagesDir+filesep+“upsampledImages”;residualDirName = trainImagesDir+filesep+“residualImages”;
使用helper函数createVDSRTrainingSet
对训练数据进行预处理。该函数作为支持文件附加到示例中。万博1manbetx
中的每个原始图像,helper函数执行这些操作trainImages
:
将图像转换为YCbCr颜色空间
通过缩小亮度(Y)通道的不同比例因子来创建样本低分辨率图像,然后使用双三次插值将图像调整到原始大小
计算原始图像和调整大小的图像之间的差异。
将调整大小的图像和残留图像保存到磁盘。
scaleFactors = [2 3 4];createVDSRTrainingSet (pristineImages scaleFactors、upsampledDirName residualDirName);
定义训练集的预处理管道
在这个例子中,网络输入是使用双三次插值进行上采样的低分辨率图像。期望的网络响应是残差图像。创建一个名为upsampledImages
从输入图像文件的集合。创建一个名为residualImages
从计算残留图像文件的集合。两个数据存储都需要一个辅助函数,matRead
,从图像文件中读取图像数据。该函数作为支持文件附加到示例中。万博1manbetx
upsampledImages = imageDatastore(upsampledDirName,FileExtensions=“.mat”ReadFcn = @matRead);residualImages = imageDatastore(residualDirName,FileExtensions=“.mat”ReadFcn = @matRead);
创建一个imageDataAugmenter
(深度学习工具箱)指定数据增强的参数。在训练过程中使用数据增强来改变训练数据,这有效地增加了可用的训练数据量。在这里,增广器指定随机旋转90度和随机反射x -方向。
augmenter = imageDataAugmenter(…randi RandRotatio = @ () ([0, 1], 1) * 90,…RandXReflection = true);
创建一个randomPatchExtractionDatastore
它从上采样和残留图像数据存储中执行随机补丁提取。补丁提取是从单个较大的图像中提取大量小图像补丁或瓷砖的过程。这种类型的数据增强经常用于图像到图像的回归问题,其中许多网络架构可以在非常小的输入图像大小上进行训练。这意味着可以从原始训练集中的每张全尺寸图像中提取大量的patch,这大大增加了训练集的大小。
patchSize = [41 41];patchesPerImage = 64;dsTrain = randompatchextracactiondatastore (upsampledImages,residualImages,patchSize,…DataAugmentation =增压器,PatchesPerImage = PatchesPerImage);
结果的数据存储,dsTrain
,在epoch的每次迭代中向网络提供小批量数据。预览从数据存储读取的结果。
inputBatch =预览(dsTrain);disp (inputBatch)
InputImage ResponseImage ______________ ______________ { 41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}{41×41双}
设置VDSR层
本例使用深度学习工具箱™中的41个单独层定义了VDSR网络,包括:
imageInputLayer
(深度学习工具箱)-图像输入层convolution2dLayer
(深度学习工具箱)-用于卷积神经网络的二维卷积层reluLayer
(深度学习工具箱)-校正线性单元(ReLU)层regressionLayer
(深度学习工具箱)神经网络的回归输出层
第一层,imageInputLayer
,操作图像补丁。patch的大小基于网络的接受场,它是影响网络最顶层响应的空间图像区域。理想情况下,网络接受域与图像大小相同,以便该域可以看到图像中的所有高级特征。在这种情况下,对于一个网络用D卷积层数,感受野为(2D+ 1)————(2D+ 1)。
VDSR有20个卷积层,因此接收野和图像补丁大小为41 × 41。图像输入层接受带有一个通道的图像,因为VDSR仅使用亮度通道进行训练。
networkDepth = 20;firstLayer = imageInputLayer([41 41 1],Name=“InputLayer”归一化=“没有”);
图像输入层后面是一个2-D卷积层,其中包含64个大小为3 × 3的滤波器。小批大小决定过滤器的数量。对每个卷积层的输入进行零垫,使特征映射在每次卷积后保持与输入相同的大小。他的方法3.]初始化权重为随机值,使神经元学习不对称。每个卷积层后面是一个ReLU层,它在网络中引入非线性。
卷积层=卷积2dlayer(3,64,填充=1,…WeightsInitializer =“他”BiasInitializer =“零”、名称=“Conv1”);
指定一个ReLU层。
relLayer = reluLayer(Name=“ReLU1”);
中间层包含18个交替的卷积和整流线性单元层。每个卷积层包含64个大小为3 × 3 × 64的过滤器,其中过滤器在64个通道上的3 × 3空间区域上操作。像以前一样,ReLU层跟随每个卷积层。
middleLayers = [convLayer relLayer];为layerNumber = 2:networkDepth-1 convLayer =卷积2dlayer (3,64,Padding=[1 1],…WeightsInitializer =“他”BiasInitializer =“零”,…Name =“Conv”+ num2str (layerNumber));relLayer = reluLayer(Name=“ReLU”+ num2str (layerNumber));middleLayers = [middleLayers convLayer relLayer];结束
倒数第二层是一个卷积层,其大小为3 × 3 × 64,用于重建图像。
卷积层=卷积2dlayer(3,1,填充=[1 1],…WeightsInitializer =“他”BiasInitializer =“零”,…NumChannels = 64,名字=“Conv”+ num2str (networkDepth));
最后一层是回归层,而不是ReLU层。回归层计算残差图像与网络预测之间的均方误差。
finalllayers = [convLayer regressionLayer(Name=“FinalRegressionLayer”));
连接所有层以形成VDSR网络。
layers = [firstLayer middleLayers finalLayers];
指定培训项目
使用动量随机梯度下降(SGDM)优化训练网络。属性指定SGDM的超参数设置trainingOptions
(深度学习工具箱)函数。学习率为初始值0.1
每10个周期减少10倍。训练100个纪元。
训练一个深度网络是很耗时的。通过指定高学习率来加速培训。然而,这可能会导致网络的梯度爆炸或不受控制地增长,从而阻止网络成功训练。若要将渐变保持在有意义的范围内,请通过指定“GradientThreshold”
作为0.01
,并指定“GradientThresholdMethod”
使用梯度的l2范数。
maxEpochs = 100;epochIntervals = 1;initLearningRate = 0.1;learningRateFactor = 0.1;L2reg = 0.0001;miniBatchSize = 64;选项= trainingOptions(“个”,…动量= 0.9,…InitialLearnRate = initLearningRate,…LearnRateSchedule =“分段”,…LearnRateDropPeriod = 10,…LearnRateDropFactor = learningRateFactor,…L2Regularization = l2reg,…MaxEpochs = MaxEpochs,…MiniBatchSize = MiniBatchSize,…GradientThresholdMethod =“l2norm”,…GradientThreshold = 0.01,…情节=“训练进步”,…Verbose = false);
培训网络
默认情况下,该示例加载预训练版本的VDSR网络,该网络已被训练为针对比例因子2、3和4的超分辨图像。预训练的网络使您能够执行测试图像的超分辨率,而无需等待训练完成。
若要训练VDSR网络,请设置doTraining
变量转换为真正的
.训练网络使用trainNetwork
(深度学习工具箱)函数。
如果有GPU,可以在GPU上进行训练。使用GPU需要并行计算工具箱™和支持CUDA®的NVIDIA®GPU。有关更多信息,请参见GPU计算要求(并行计算工具箱).在NVIDIA Titan X上训练大约需要6个小时。
doTraining =假;如果doTraining net = trainNetwork(dsTrain,layers,options);modelDateTime = string(datetime(“现在”格式=“yyyy-MM-dd-HH-mm-ss”));保存(“trainedVDSR——”+ modelDateTime +“.mat”,“净”);其他的负载(“trainedVDSRNet.mat”);结束
使用VDSR网络实现单幅图像超分辨率
要使用VDSR网络执行单图像超分辨率(SISR),请遵循本示例的其余步骤:
从高分辨率参考图像创建低分辨率示例图像。
使用双三次插值对低分辨率图像进行SISR,双三次插值是一种传统的图像处理解决方案,不依赖于深度学习。
利用VDSR神经网络对低分辨率图像进行SISR。
用双三次插值和VDSR对重建的高分辨率图像进行直观比较。
通过量化图像与高分辨率参考图像的相似度来评估超分辨率图像的质量。
创建样本低分辨率图像
测试数据集,testImages
,包含20张在图像处理工具箱中提供的未失真图像。将图像加载到imageDatastore
并以蒙太奇的方式展示这些图像。
fileNames = [“sherlock.jpg”,“peacock.jpg”,“fabric.png”,“greens.jpg”,…“hands1.jpg”,“kobi.png”,“lighthouse.png”,“office_4.jpg”,…“onion.png”,“pears.png”,“yellowlily.jpg”,“indiancorn.jpg”,…“flamingos.jpg”,“sevilla.jpg”,“llama.jpg”,“parkavenue.jpg”,…“strawberries.jpg”,“trailer.jpg”,“wagon.jpg”,“football.jpg”];filePath = fullfile(matlabroot,“工具箱”,“图片”,“imdata”) + filesep;filePathNames = strcat(filePath,文件名);testImages = imageDatastore(filePathNames);
以蒙太奇的方式显示测试图像。
蒙太奇(testImages)
选择一个用于测试超分辨率网络的测试图像。
testImage =“sherlock.jpg”;Ireference = imread(testImage);Ireference = im2double(Ireference);imshow (Ireference)标题(“高分辨率参考图像”)
使用创建高分辨率参考图像的低分辨率版本imresize
缩放系数为0.25。图像的高频分量在降尺度过程中丢失。
scaleFactor = 0.25;Ilowres = imresize(Ireference,scaleFactor,“双三次的”);imshow (Ilowres)标题(“低分辨率图像”)
利用双三次插值提高图像分辨率
在没有深度学习的情况下提高图像分辨率的标准方法是使用双三次插值。使用双三次插值对低分辨率图像进行升级,使生成的高分辨率图像与参考图像大小相同。
[nrows,ncols,np] = size(Ireference);Ibicubic = imresize(Ilowres,[nrows ncols],“双三次的”);imshow (Ibicubic)标题(双三次插值获得高分辨率图像)
利用预训练的VDSR网络提高图像分辨率
回想一下,VDSR只使用图像的亮度通道进行训练,因为人类的感知对亮度变化比对颜色变化更敏感。
将低分辨率图像从RGB颜色空间转换为亮度(Iy
)和色度(银行独立委员会
而且只有几
)通道rgb2ycbcr
函数。
Iycbcr = rgb2ycbcr(Ilowres);Iy = Iycbcr(:,:,1);Icb = Iycbcr(:,:,2);Icr = Iycbcr(:,:,3);
使用双三次插值提升亮度和两个色度通道。上采样的色度通道,Icb_bicubic
而且Icr_bicubic
,无需进一步处理。
Iy_bicubic = imresize(Iy,[nrows ncols],“双三次的”);Icb_bicubic = imresize(Icb,[nrows ncols],“双三次的”);Icr_bicubic = imresize(Icr,[nrows ncols],“双三次的”);
传递放大的亮度分量,Iy_bicubic
,通过训练好的VDSR网络。观察激活
(深度学习工具箱)最后一层(回归层)。网络的输出是期望的残差图像。
Iresidual = activation (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获得的高分辨率图像”)
视觉和定量比较
为了更好地从视觉上理解高分辨率图像,请检查每张图像中的一个小区域。使用向量指定感兴趣的区域(ROI)roi
格式为[xy宽度高度].元素定义了左上角的x坐标和y坐标,以及ROI的宽度和高度。
ROI = [360 50 400 350];
将高分辨率图像裁剪到此ROI,并将结果显示为蒙太奇。与使用双三次插值生成的高分辨率图像相比,VDSR图像具有更清晰的细节和更清晰的边缘。
蒙太奇({imcrop (Ibicubic roi), imcrop (Ivdsr roi)})标题(使用双三次插值的高分辨率结果(左)vs. VDSR(右));
使用图像质量度量来定量比较使用双三次插值的高分辨率图像与VDSR图像。参考图像为原始高分辨率图像,Ireference
,然后再准备样本低分辨率图像。
测量每个图像相对于参考图像的峰值信噪比(PSNR)。PSNR值越大,通常表示图像质量越好。看到psnr值
有关此指标的更多信息。
bicubicPSNR = psnr(Ibicubic,Ireference)
bicubicPSNR = 38.4747
vdsrPSNR = psnr(Ivdsr,Ireference)
vdsrPSNR = 39.2346
测量每个图像的结构相似指数(SSIM)。SSIM评估图像的三个特征的视觉影响:亮度,对比度和结构,相对于参考图像。SSIM值越接近1,说明测试图像与参考图像的一致性越好。看到ssim
有关此指标的更多信息。
bicubicSSIM = ssim(Ibicubic,Ireference)
bicubicSSIM = 0.9861
vdsr = ssim(Ivdsr,Ireference)
vdsrSSIM = 0.9874
使用自然图像质量评估器(NIQE)测量感知图像质量。NIQE分数越小,知觉质量越好。看到niqe
有关此指标的更多信息。
bicubicNIQE = niqe(bicicubic)
bicubicNIQE = 5.1721
vdsrNIQE = niqe(Ivdsr)
vdsrNIQE = 4.7612
计算整个测试图像的平均PSNR和SSIM的比例因子2,3和4。为了简单起见,您可以使用helper函数,vdsrMetrics
,以计算平均指标。该函数作为支持文件附加到示例中。万博1manbetx
scaleFactors = [2 3 4];vdsrMetrics(净testImages scaleFactors);
结果比例因子2双三次的平均PSNR值= 31.467070平均PSNR VDSR = 31.481973平均SSIM双三次的= 0.935820平均SSIM VDSR = 0.947057结果比例因子3双三次的平均PSNR值= 28.107057平均PSNR VDSR = 28.430546平均SSIM双三次的= 0.883927平均SSIM VDSR = 0.894634结果比例因子4双三次的平均PSNR值= 27.066129平均PSNR VDSR = 27.846590平均SSIM双三次的= 0.863270平均SSIM VDSR = 0.878101
对于每个比例因子,VDSR比双三次插值具有更好的度量分数。
参考文献
[1] Kim, J., J. K. Lee, K. M. Lee。“使用非常深度卷积网络的精确图像超分辨率。”IEEE论文集®计算机视觉与模式识别会议“,.2016,第1646-1654页。
[2]格鲁宾格,M. P.克拉夫,H. Müller和T.迪塞勒。IAPR TC-12基准:视觉信息系统的新评估资源基于内容的图像检索语言资源文集.意大利热那亚。第五卷,2006年5月,第10页
[3]何K,张旭光,任淑娟,孙杰。“深入研究整流器:在ImageNet分类上超越人类水平的性能。”IEEE计算机视觉国际会议论文集, 2015, pp. 1026-1034。
另请参阅
randomPatchExtractionDatastore
|rgb2ycbcr
|ycbcr2rgb
|trainingOptions
(深度学习工具箱)|trainNetwork
(深度学习工具箱)|变换
|结合
相关的话题
- 用于深度学习的图像预处理(深度学习工具箱)
- 深度学习层列表(深度学习工具箱)