主要内容

使用深度学习提高图像分辨率

这个例子展示了如何使用极深超分辨率(VDSR)神经网络从低分辨率图像创建高分辨率图像。

超分辨率是从低分辨率图像创建高分辨率图像的过程。本例考虑单图像超分辨率(SISR),其目标是从一个低分辨率图像中恢复一个高分辨率图像。SISR具有挑战性,因为高频图像内容通常无法从低分辨率图像中恢复。没有高频信息,高分辨率图像的质量是有限的。此外,SISR是一个病态的问题,因为一个低分辨率的图像可以产生多个可能的高分辨率图像。

一些技术,包括深度学习算法,已经被提出来执行SISR。本例探讨了一种用于SISR的深度学习算法,称为极深超分辨率(VDSR) [1].

VDSR网络

VDSR是一种卷积神经网络架构,旨在执行单幅图像的超分辨率[1].VDSR网络学习低分辨率和高分辨率图像之间的映射。这种映射是可能的,因为低分辨率和高分辨率图像具有相似的图像内容,主要是在高频细节上不同。

VDSR采用残差学习策略,这意味着网络学习估计残差图像。在超分辨率背景下,残差图像是高分辨率参考图像与低分辨率图像之间的差值,低分辨率图像通过双三次插值进行放大,以匹配参考图像的大小。残差图像包含关于图像高频细节的信息。

VDSR网络从彩色图像的亮度中检测残差图像。图像的亮度通道,Y,表示每个像素的亮度,通过红、绿、蓝像素值的线性组合。相比之下,图像的两个色度通道,Cb而且Cr,是表示色差信息的红、绿、蓝像素值的不同线性组合。VDSR只使用亮度通道进行训练,因为人类的感知对亮度的变化比对颜色的变化更敏感。

如果 Y res 高分辨率图像的亮度和 Y lowres 亮度是否是使用双三次插值放大的低分辨率图像,那么VDSR网络的输入为 Y lowres 网络学会了预测 Y 剩余 Y highres - Y lowres 从训练数据中。

在VDSR网络学会估计残差图像后,可以将估计的残差图像添加到上采样的低分辨率图像中,然后将图像转换回RGB颜色空间,从而重构高分辨率图像。

比例因子将参考图像的大小与低分辨率图像的大小联系起来。随着比例因子的增加,由于低分辨率图像丢失了更多关于高频图像内容的信息,SISR变得更加病态。VDSR通过使用大的接受场解决了这个问题。本例使用尺度增强来训练具有多个尺度因子的VDSR网络。由于网络可以从较小的尺度因子中利用图像上下文,因此尺度增强可以改善在较大尺度因子下的结果。此外,VDSR网络可以泛化接受具有非整数比例因子的图像。

下载培训和测试数据

下载IAPR TC-12基准,由2万张静止自然图像组成[2].数据集包括人物、动物、城市等的照片。数据文件的大小为~1.8 GB。如果您不想下载训练数据集,那么您可以通过输入加载预先训练的VDSR网络负载(“trainedVDSRNet.mat”);在命令行。然后,直接去利用VDSR网络实现单幅图像超分辨率节。

使用助手函数,downloadIAPRTC12Data,下载有关资料。该函数作为支持文件附加到示例中。指定dataDir作为数据的期望位置。

dataDir =tempdir;downloadIAPRTC12Data (dataDir);

本例将使用IAPR TC-12基准数据的一小部分来训练网络。加载imageCLEF训练数据。所有图片均为32位JPEG彩色图片。

trainImagesDir = fullfile (dataDir,“iaprtc12”“图片”“2”);ext = [“jpg”“bmp格式”“使用”];pristineImages = imageDatastore (trainImagesDir FileExtensions = ext);

列出训练图像的数量。

元素个数(pristineImages.Files)
ans = 616

准备训练数据

为了创建一个训练数据集,生成由上采样图像和相应的残差图像组成的图像对。

上采样的图像作为MAT文件存储在磁盘上的目录中upsampledDirName.计算得到的代表网络响应的残差图像作为MAT文件存储在磁盘上的目录中residualDirName.MAT文件存储为数据类型训练网络时,精确度更高。

upsampledDirName = trainImagesDir + filesep +“upsampledImages”;residualDirName = trainImagesDir + filesep +“residualImages”

使用helper函数createVDSRTrainingSet预处理训练数据。该函数作为支持文件附加到示例中。

中的每个原始图像,助手函数执行这些操作trainImages

  • 将图像转换为YCbCr颜色空间

  • 通过不同的比例因子缩小亮度(Y)通道以创建低分辨率图像样本,然后使用双三次插值将图像调整到原始大小

  • 计算原始图像和调整大小图像之间的差异。

  • 将调整后的图像和残留图像保存到磁盘。

scaleFactors = [2 3 4];createVDSRTrainingSet (pristineImages scaleFactors、upsampledDirName residualDirName);

为训练集定义预处理管道

在本例中,网络输入是使用双三次插值进行上采样的低分辨率图像。期望的网络响应是残差图像。创建一个名为upsampledImages从集合的输入图像文件。创建一个名为residualImages从收集的计算残差图像文件。两个数据存储都需要一个helper函数,matRead,从图像文件中读取图像数据。该函数作为支持文件附加到示例中。

upsampledImages = imageDatastore (upsampledDirName FileExtensions =“.mat”ReadFcn = @matRead);residualImages = imageDatastore (residualDirName FileExtensions =“.mat”ReadFcn = @matRead);

创建一个imageDataAugmenter它指定数据扩充的参数。在训练期间使用数据增强来改变训练数据,这有效地增加了可用的训练数据的数量。在这里,增广器指定随机旋转90度和随机反射x -方向。

增量= imageDataAugmenter (...randi RandRotatio = @ () ([0, 1], 1) * 90,...RandXReflection = true);

创建一个randomPatchExtractionDatastore(图像处理工具箱)它从上采样的和残留的图像数据存储中执行随机的补丁提取。补丁提取是从单个较大的图像中提取大量小图像补丁(或瓷砖)的过程。这种类型的数据增强经常用于图像到图像的回归问题,其中许多网络体系结构可以在非常小的输入图像尺寸上进行训练。这意味着可以从原始训练集中的每张全尺寸图像中提取大量的patch,这大大增加了训练集的大小。

patchSize = [41 41];patchesPerImage = 64;dsTrain = randomPatchExtractionDatastore (upsampledImages residualImages patchSize,...DataAugmentation =增压器,PatchesPerImage = PatchesPerImage);

由此产生的数据存储,dsTrain,在历的每次迭代时向网络提供小批数据。预览从数据存储读取的结果。

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,操作图像补丁。patch的大小基于网络接受域,网络接受域是影响网络最顶层响应的空间图像区域。理想情况下,网络接受场与图像大小相同,以便该场可以看到图像中的所有高级特征。在这种情况下,对于一个网络来说D卷积层,感受野为(2D+ 1)————(2D+ 1)。

VDSR有20个卷积层,因此接收场和图像补丁大小为41 × 41。图像输入层接受具有一个通道的图像,因为VDSR只使用亮度通道进行训练。

networkDepth = 20;firstLayer = imageInputLayer([41 41 1],Name=“InputLayer”归一化=“没有”);

图像输入层后面是一个包含64个大小为3乘3的滤波器的二维卷积层。小批大小决定过滤器的数量。对每个卷积层的输入进行零填充,使每次卷积后的特征映射保持与输入相同的大小。他的方法3.初始化权值为随机值,这样神经元学习就不对称了。每个卷积层后面跟着一个ReLU层,这引入了网络的非线性。

convLayer = convolution2dLayer(64,填充= 1,...WeightsInitializer =“他”BiasInitializer =“零”、名称=“Conv1”);

指定一个ReLU层。

relLayer = reluLayer (Name =“ReLU1”);

中间层包含18个交替卷积和整流线性单元层。每个卷积层包含64个大小为3 × 3 × 64的过滤器,其中一个过滤器在跨越64个通道的3 × 3空间区域上工作。和前面一样,ReLU层跟在每个卷积层后面。

middleayers = [convLayer relLayer];layerNumber = 2:networkDepth-1 convLayer = convolution2dLayer(3,64,Padding=[1 1],...WeightsInitializer =“他”BiasInitializer =“零”...Name =“Conv”+ num2str (layerNumber));relLayer = reluLayer (Name =“ReLU”+ num2str (layerNumber));middleelayers = [middleelayers convLayer relLayer];结束

倒数第二层是一个卷积层,它有一个大小为3 × 3 × 64的过滤器,用于重建图像。

convLayer = convolution2dLayer(3,1,Padding=[1 1],...WeightsInitializer =“他”BiasInitializer =“零”...NumChannels = 64,名字=“Conv”+ num2str (networkDepth));

最后一层是回归层,而不是ReLU层。回归层计算残差图像与网络预测之间的均方误差。

finalLayers = [convLayer regressionLayer(Name=“FinalRegressionLayer”));

将所有层连接起来形成VDSR网络。

layers = [firstLayer middleelayers 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 =字符串(datetime (“现在”格式=“yyyy-MM-dd-HH-mm-ss”));保存(“trainedVDSR——”+ modelDateTime +“.mat”“净”);其他的负载(“trainedVDSRNet.mat”);结束

利用VDSR网络实现单幅图像超分辨率

要使用VDSR网络执行单幅图像超分辨率(SISR),请遵循本示例的其余步骤:

  • 从高分辨率参考图像创建低分辨率示例图像。

  • 使用双三次插值(传统的图像处理方案,不依赖深度学习)对低分辨率图像进行SISR。

  • 利用VDSR神经网络对低分辨率图像进行SISR。

  • 用双三次插值和VDSR对重构的高分辨率图像进行了可视化比较。

  • 通过量化图像与高分辨率参考图像的相似度来评价超分辨图像的质量。

创建样本低分辨率图像

测试数据集,testImages,包含在图像处理工具箱™中附带的20张未失真图像。将图像加载到imageDatastore并以蒙太奇的方式展示这些图像。

文件名= [“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) = (Ireference)大小;Ibicubic = imresize(Ilowres,[nrows ncols],“双三次的”);imshow (Ibicubic)标题(用双三次插值法获得高分辨率图像

利用预训练的VDSR网络提高图像分辨率

回想一下,VDSR只使用图像的亮度通道进行训练,因为人类的感知对亮度的变化比对颜色的变化更敏感。

将低分辨率图像从RGB颜色空间转换为亮度(Iy)和色度(银行独立委员会而且只有几)通道rgb2ycbcr(图像处理工具箱)函数。

Iycbcr = rgb2ycbcr (Ilowres);Iy = Iycbcr (:: 1);银行独立委员会= 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 =激活(净、Iy_bicubic 41);Iresidual =双(Iresidual);imshow (Iresidual[])标题(VDSR残留图像

将残差图像添加到放大亮度分量中,得到高分辨率VDSR亮度分量。

Isr = Iy_bicubic + Iresidual;

连接高分辨率VDSR亮度组件与放大颜色组件。方法将图像转换为RGB颜色空间ycbcr2rgb(图像处理工具箱)函数。结果是使用VDSR的最终高分辨率彩色图像。

Ivdsr = ycbcr2rgb(猫(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)})标题(使用双三次插值(左)和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
vdsrSSIM = ssim (Ivdsr Ireference)
vdsrSSIM = 0.9874

使用自然图像质量评估器(NIQE)测量感知图像质量。NIQE分数越小,感知质量越好。看到niqe(图像处理工具箱)有关此指标的更多信息。

bicubicNIQE = niqe (Ibicubic)
bicubicNIQE = 5.1721
vdsrNIQE = niqe (Ivdsr)
vdsrNIQE = 4.7612

计算整个测试图像集在比例因子2,3,4下的平均PSNR和SSIM。为了简单起见,您可以使用helper函数,vdsrMetrics,计算平均指标。该函数作为支持文件附加到示例中。

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]金,J., J. K.李,K. M.李。“使用非常深度卷积网络的精确图像超分辨率。”IEEE学报®计算机视觉与模式识别会议.2016年,页1646 - 1654。

[2]格鲁宾格,M., P.克拉夫,H. Müller,和T.德塞勒。IAPR TC-12基准:视觉信息系统的新评估资源。OntoImage 2006基于内容的图像检索语言资源.意大利热那亚。第五卷,2006年5月,第10页。

[3]何凯,张旭,任硕,孙杰。深入研究整流器:在ImageNet分类上超越人类水平的性能。IEEE计算机视觉国际会议论文集, 2015, pp. 1026-1034。

另请参阅

||||||

相关的话题

Baidu
map