使用深度学习的单幅图像超分辨率
这个例子展示了如何训练一个非常深的超分辨率(VDSR)神经网络,然后使用VDSR网络从一张低分辨率图像中估计出一张高分辨率图像。
该示例展示了如何训练VDSR网络,并提供了预先训练的VDSR网络。如果您选择训练VDSR网络,强烈建议使用具有cuda功能、计算能力3.0或更高版本的NVIDIA™GPU。GPU的使用需要并行计算工具箱™。
如果你不想下载训练数据集或训练网络,那么你可以通过输入加载预训练的VDSR网络负载(“trainedvdsr时代- 100 scalefactors - 234. -垫”);
在命令行。然后,直接去使用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].数据集包括人物、动物、城市等的照片。你可以使用helper函数,downloadIAPRTC12Data
下载资料。数据文件的大小为~1.8 GB。
imagesDir = tempdir;url =“http://www-i6.informatik.rwth-aachen.de/imageclef/resources/iaprtc12.tgz”;downloadIAPRTC12Data (url, imagesDir);
本例将使用IAPR TC-12基准数据的一小部分来训练网络。加载imageCLEF训练数据。所有图像均为32位JPEG彩色图像。
trainImagesDir = fullfile(imagesDir,“iaprtc12”,“图片”,“2”);Exts = {“jpg”,bmp格式的,“使用”};trainImages = imageDatastore(trainImagesDir,“FileExtensions”ext);
列出训练图像的数量。
元素个数(trainImages.Files)
Ans = 616
定义用于训练的小批量数据存储
一个小批量数据存储用于将训练数据输入网络。此示例定义了一个名为vdsrImagePatchDatastore
,作为一种生成增强图像补丁以训练VDSR网络的方便方法。
的vdsrImagePatchDatastore
从低分辨率输入图像中提取斑块,并在不同尺度因子下对斑块进行放大。接下来,数据存储使用旋转和反射来增强补丁x方向。数据增强在增加训练数据量方面很有用。最后,数据预处理创建与每个增强图像补丁对应的剩余图像补丁。低分辨率图像补丁作为网络输入。剩余的补丁是期望的网络输出。
每个迷你批包含64个41 × 41像素的补丁(稍后在设置VDSR层时解释了补丁大小的选择)。在训练过程中,每张图像只提取一个迷你批次,所有的补丁都将从图像中的随机位置提取。设置”BatchesPerImage
到每个小批量每张图像要提取的随机补丁的数量。为了训练一个多尺度因子网络,设置ScaleFactor
到[2 3 4]。
miniBatchSize = 64;scaleFactors = [2 3 4];来源= vdsrImagePatchDatastore(trainImages,...“MiniBatchSize”miniBatchSize,...“PatchSize”41岁的...“BatchesPerImage”,1,...“ScaleFactor”, scaleFactors);
的vdsrImagePatchDatastore
在历元的每个迭代中向网络提供小批量数据。在数据存储上执行读取操作以查看数据。
inputBatch = read(source);总结(inputBatch)
变量:lowResolutionPatches: 64×1 cell residuals: 64×1 cell
设置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],“名字”,“InputLayer”,“归一化”,“没有”);
图像输入层后面是一个2-D卷积层,其中包含64个大小为3 × 3的滤波器。小批大小决定过滤器的数量。对每个卷积层的输入进行零垫,使特征映射在每次卷积后保持与输入相同的大小。他的方法[3]将权重初始化为随机值,使神经元学习不对称。每个卷积层后面是一个ReLU层,它在网络中引入非线性。
卷积层=卷积2dlayer (3,64,“填充”,1,...“名字”,“Conv1”);convolutionLayer。权重=√(2/(9*64))*randn(3,3,1,64);convolutionLayer。偏差= 0 (1,1,64);
指定一个ReLU层。
relLayer = relullayer (“名字”,“ReLU1”);
中间层包含18个交替的卷积和整流线性单元层。每个卷积层包含64个大小为3 × 3 × 64的过滤器,其中过滤器在64个通道上的3 × 3空间区域上操作。他的方法[3]将权重初始化为随机值。像以前一样,ReLU层跟随每个卷积层。
middleLayers = [convolutionLayer relLayer];为layerNumber = 2:networkDepth-1 conv2dLayer =卷积2dlayer (3,64,...“填充”[1],...“名字”, (“Conv”num2str (layerNumber)]);% He初始化conv2dLayer。权重=√(2/(9*64))*randn(3,3,64,64);conv2dLayer。偏差= 0 (1,1,64);relLayer = relullayer (“名字”, (“ReLU”num2str (layerNumber)]);middleLayers = [middleelayers conv2dLayer relLayer];结束
倒数第二层是一个卷积层,其大小为3x3x64,用于重建图像。
conv2dLayer =卷积2dlayer (3,1,...“NumChannels”, 64,...“填充”[1],...“名字”, (“Conv”num2str (networkDepth)]);conv2dLayer。权重=√(2/(9*64))*randn(3,3,64,1);conv2dLayer。偏差= 0 (1,1,1);
最后一层是回归层,而不是ReLU层。回归层计算残差图像与网络预测之间的均方误差。
finalLayers = [conv2dLayer regressionLayer(“名字”,“FinalRegressionLayer”));
连接所有层以形成VDSR网络。
layers = [firstLayer middleLayers finalLayers];
或者,您可以使用这个辅助函数来创建VDSR层。
layers = vdsrLayers();
指定培训项目
使用动量随机梯度下降(SGDM)优化训练网络。属性指定SDGM的超参数设置trainingOptions
函数。学习率最初设置为0.1,然后每20个epoch降低10倍。训练100个纪元。
训练一个深度网络是很耗时的。通过指定高学习率来加速培训。然而,这可能会导致网络的梯度爆炸或不受控制地增长,从而阻止网络成功训练。为了保持梯度在一个有意义的范围内,启用梯度剪辑通过设置“GradientThreshold不
值为0.01,并指定“GradientThresholdMethod”
使用梯度的l2范数。
maxEpochs = 100;epochIntervals = 1;initLearningRate = 0.1;learningRateFactor = 0.1;L2reg = 0.0001;选项= trainingOptions(“个”,...“动量”, 0.9,...“InitialLearnRate”initLearningRate,...“LearnRateSchedule”,“分段”,...“LearnRateDropPeriod”10...“LearnRateDropFactor”learningRateFactor,...“L2Regularization”l2reg,...“MaxEpochs”maxEpochs,...“MiniBatchSize”miniBatchSize,...“GradientThresholdMethod”,“l2norm”,...“GradientThreshold”, 0.01);
培训网络
配置培训选项和小批量数据存储后,使用trainNetwork
函数。为了训练网络,设置doTraining
参数真正的
.强烈建议使用具有cuda功能、计算能力3.0或更高版本的NVIDIA™GPU进行培训。
如果你留着doTraining
参数在下面的代码中为假
,然后该示例返回预先训练的VDSR网络,该网络已被训练为超分辨率图像的比例因子2、3和4。
注意:在NVIDIA(TM) Titan X上进行训练大约需要6个小时,根据GPU硬件的不同,训练时间可能会更长。
doTraining = false;如果doTraining modelDateTime = datestr(现在,“dd-mmm-yyyy-HH-MM-SS”);net = trainNetwork(源,层,选项);保存([“trainedVDSR -”modelDateTime的时代,num2str (maxEpochs * epochIntervals)“ScaleFactors -”num2str (234)“.mat”),“净”,“选项”);其他的负载(“trainedvdsr时代- 100 scalefactors - 234. -垫”);结束
使用VDSR网络实现单幅图像超分辨率
要使用VDSR网络执行单图像超分辨率(SISR),请遵循本示例的其余步骤。该示例的其余部分展示了如何:
从高分辨率参考图像创建低分辨率示例图像。
使用双三次插值对低分辨率图像进行SISR,双三次插值是一种传统的图像处理解决方案,不依赖于深度学习。
利用VDSR神经网络对低分辨率图像进行SISR。
用双三次插值和VDSR对重建的高分辨率图像进行直观比较
通过量化图像与高分辨率参考图像的相似度来评估超分辨率图像的质量。
创建样本低分辨率图像
创建一个低分辨率图像,将用于比较使用深度学习的超分辨率结果和使用双三次插值等传统图像处理技术的结果。测试数据集,testImages
,包含21张在图像处理工具箱中提供的未失真图像。将图像加载到imageDatastore
.
Exts = {“jpg”,“使用”};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,“工具箱”,“图片”,“imdata”) filesep);filePathNames = strcat(filePath,文件名);testImages = imageDatastore(filePathNames,“FileExtensions”ext);
以蒙太奇的方式显示测试图像。
蒙太奇(testImages)
选择一个图像作为超分辨率的参考图像。您可以选择使用自己的高分辨率图像作为参考图像。
指数= 1;从测试映像数据存储中读取的映像的索引Ireference = readimage(testImages, index);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 = [320 30 480 400];
将高分辨率图像裁剪到此ROI,并将结果显示为蒙太奇。
蒙太奇({imcrop (Ibicubic roi), imcrop (Ivdsr roi)})标题(使用双三次插值的高分辨率结果(左)vs. VDSR(右));
VDSR图像具有更清晰的细节和更清晰的边缘。
使用图像质量度量来定量比较使用双三次插值的高分辨率图像与VDSR图像。参考图像为原始高分辨率图像,Ireference
,然后再准备样本低分辨率图像。
测量每个图像相对于参考图像的峰值信噪比(PSNR)。PNSR值越大,通常表示图像质量越好。看到psnr值
有关此指标的更多信息。
bicubicPSNR = psnr(Ibicubic,Ireference)
bicubicPSNR = 38.4747
vdsrPSNR = psnr(Ivdsr,Ireference)
vdsrPSNR = 39.4473
测量每个图像的结构相似指数(SSIM)。SSIM评估图像的三个特征的视觉影响:亮度,对比度和结构,相对于参考图像。SSIM值越接近1,说明测试图像与参考图像的一致性越好。看到ssim
有关此指标的更多信息。
bicubicSSIM = ssim(Ibicubic,Ireference)
bicubicSSIM = 0.9861
vdsr = ssim(Ivdsr,Ireference)
vdsrSSIM = 0.9878
使用自然图像质量评估器(NIQE)测量感知图像质量。NIQE分数越小,知觉质量越好。看到niqe
有关此指标的更多信息。
bicubicNIQE = niqe(bicicubic)
bicubicNIQE = 5.1719
vdsrNIQE = niqe(Ivdsr)
vdsrNIQE = 4.7463
计算整个测试图像的平均PSNR和SSIM的比例因子2,3和4。这些是用来定义vdsrImagePatchDatastore
.为了简单起见,您可以使用helper函数,superResolutionMetrics
,以计算平均指标。
superResolutionMetrics(净testImages scaleFactors);
结果比例因子2双三次的平均PSNR值= 31.809683平均PSNR VDSR = 32.915853平均SSIM双三次的= 0.938194平均SSIM VDSR = 0.953473结果比例因子3双三次的平均PSNR值= 28.170441平均PSNR VDSR = 28.802722平均SSIM双三次的= 0.884381平均SSIM VDSR = 0.898248结果比例因子4双三次的平均PSNR值= 27.010839平均PSNR VDSR = 28.087250平均SSIM双三次的= 0.861604平均SSIM VDSR = 0.882349
对于每个尺度因子,与双三次插值相比,VDSR具有更好的度量分数。
总结
这个例子展示了如何为多个比例因子创建和训练一个VDSR网络,然后使用该网络通过超分辨率来提高图像分辨率。以下是训练网络的步骤:
下载培训数据。
定义一个自定义的小批数据存储,称为
VDSRImagePatchDatastore
,从低分辨率图像中提取斑块,并计算参考高分辨率训练图像中对应斑块的目标残差。该数据存储用于向网络提供训练数据。定义VDSR网络的层。
指定培训选项。
训练网络使用
trainNetwork
函数。
在训练VDSR网络或加载预训练的VDSR网络之后,该示例在低分辨率图像上执行超分辨率。该示例使用双三次插值(不使用深度学习)将VDSR结果与超分辨率进行比较。VDSR在感知图像质量和定量质量测量方面都优于双三次插值。
参考文献
[1] Kim, J., J. K. Lee, K. M. Lee。“使用非常深度卷积网络的精确图像超分辨率。”IEEE论文集®计算机视觉与模式识别会议,2016,pp. 1646-1654。
[2]格鲁宾格,M. P.克拉夫,H. Müller和T.迪塞勒。IAPR TC-12基准:视觉信息系统的新评估资源基于内容的图像检索语言资源文集。意大利热那亚。第五卷,2006年5月,第10页
[3]何K,张旭光,任淑娟,孙杰。“深入研究整流器:在ImageNet分类上超越人类水平的性能。”IEEE计算机视觉国际会议论文集,2015,pp. 1026-1034。
另请参阅
convolution2dLayer
|imageInputLayer
|regressionLayer
|reluLayer
|rgb2ycbcr
|trainNetwork
|trainingOptions
|ycbcr2rgb
相关的话题
- 开发自定义小批量数据存储(神经网络工具箱)