主要内容

使用深度学习的JPEG图像分块

这个例子展示了如何使用去噪卷积神经网络(DnCNN)减少图像中的JPEG压缩伪影。

图像压缩用于减少图像的内存占用。JPEG图像格式采用了一种流行且功能强大的压缩方法,它使用质量因子来指定压缩量。降低质量值会导致更高的压缩和更小的内存占用,但以牺牲图像的视觉质量为代价。

JPEG压缩是有损这意味着压缩过程会导致图像丢失信息。对于JPEG图像,这种信息损失表现为图像中的块工件。如图所示,更多的压缩会导致更多的信息丢失和更强的工件。高频内容的纹理区域,如草和云,看起来很模糊。尖锐的边缘,比如房子的屋顶和灯塔顶上的护栏,都显示出了响动。

JPEG去块是减少JPEG图像中压缩工件影响的过程。目前有几种JPEG去块方法,包括使用深度学习的更有效的方法。这个例子实现了这样一个基于深度学习的方法,它试图最小化JPEG压缩工件的影响。

DnCNN网络

这个例子使用了一个内置的深度前馈卷积神经网络,称为DnCNN.该网络主要用于从图像中去除噪声。然而,DnCNN体系结构也可以被训练来去除JPEG压缩工件或提高图像分辨率。

参考文件[1]采用了残差学习策略,这意味着DnCNN网络学会了估计残差图像。残差图像是原始图像和图像失真副本之间的区别。残差图像包含了图像失真的信息。对于本例,失真显示为JPEG阻塞工件。

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

如果 Y 原始 是亮度的原始图像和 Y 压缩 为包含JPEG压缩工件的图像的亮度,则DnCNN网络的输入为 Y 压缩 网络学会了预测 Y 剩余 Y 压缩 - Y 原始 从训练数据中。

一旦DnCNN网络学会了如何估计残差图像,它就可以通过将残差图像添加到压缩的亮度通道中,然后将图像转换回RGB颜色空间来重建压缩JPEG图像的未失真版本。

下载培训资料

下载IAPR TC-12基准,其中包括2万张静止自然图像[2].数据集包括人物、动物、城市等的照片。数据文件的大小为~1.8 GB。如果你不想下载训练数据或训练网络,那么你可以通过输入来加载预训练的DnCNN网络负载(“trainedJPEGDnCNN.mat”)在命令行。然后,直接去使用DnCNN网络执行JPEG分块节。

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

dataDir =tempdir;downloadIAPRTC12Data (dataDir);

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

trainImagesDir = fullfile(dataDir,“iaprtc12”“图片”“00”);Exts = [“jpg”“bmp格式”“使用”];imdsPristine = imageDatastore(trainImagesDir,FileExtensions=exts);

列出训练图像的数量。

元素个数(imdsPristine.Files)
Ans = 251

准备培训数据

要创建训练数据集,请读入原始图像并以具有不同压缩级别的JPEG文件格式写入图像。

指定用于呈现图像压缩工件的JPEG图像质量值。质量值必须在[0,100]范围内。较小的质量值会导致更多的压缩和更强的压缩伪影。使用小质量值的密集抽样,以便训练数据具有广泛的压缩伪影。

JPEGQuality = [5:5:40 50 60 70 80];

压缩后的映像以MAT文件的形式存储在磁盘目录中compressedImagesDir.计算出的残留图像作为MAT文件存储在磁盘上的目录中residualImagesDir.MAT文件以数据类型存储为了训练网络时更精确。

compressedImagesDir = fullfile(dataDir,“iaprtc12”“JPEGDeblockingData”“compressedImages”);residualImagesDir = fullfile(dataDir,“iaprtc12”“JPEGDeblockingData”“residualImages”);

使用helper函数createJPEGDeblockingTrainingSet对训练数据进行预处理。该函数作为支持文件附加到示例中。金宝app

对于每个原始训练图像,helper函数会写入一个质量因子为100的图像副本作为参考图像,并写入每个质量因子为100的图像副本作为网络输入。该函数以数据类型计算参考图像和压缩图像的亮度(Y)通道为了在计算残差图像时获得更高的精度。压缩后的映像以.MAT文件的形式存储在磁盘目录中compressedDirName.计算出的残留图像以.MAT文件的形式存储在磁盘目录中residualDirName

[compressedDirName,residualDirName] = createJPEGDeblockingTrainingSet(imdsPristine,JPEGQuality);

为训练创建随机补丁提取数据存储

使用随机补丁提取数据存储将训练数据输入网络。该数据存储从包含网络输入和所需网络响应的两个映像数据存储中提取随机对应的补丁。

在本例中,网络输入是压缩图像。期望的网络响应是残差图像。创建一个名为imdsCompressed从压缩图像文件的集合。创建一个名为imdsResidual从计算残留图像文件的集合。两个数据存储都需要一个辅助函数,matRead,从图像文件中读取图像数据。该函数作为支持文件附加到示例中。金宝app

imdsCompressed = imageDatastore(compressedDirName,FileExtensions=“.mat”ReadFcn = @matRead);imdsResidual = imageDatastore(residualDirName,FileExtensions=“.mat”ReadFcn = @matRead);

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

augmenter = imageDataAugmenter(...randi RandRotation = @ () ([0, 1], 1) * 90,...RandXReflection = true);

创建randomPatchExtractionDatastore(图像处理工具箱)从两个映像数据存储。指定50x50像素的补丁大小。每张图像生成128个大小为50 × 50像素的随机补丁。指定迷你批处理大小为128。

patchSize = 50;patchesPerImage = 128;dsTrain = randompatchextracactiondatastore (imdsCompressed,imdsResidual,patchSize,...PatchesPerImage = PatchesPerImage,...DataAugmentation =增压器);dsTrain。MiniBatchSize = patchesPerImage;

随机补丁提取数据存储dsTrain在历元迭代时向网络提供小批量数据。预览从数据存储读取的结果。

inputBatch =预览(dsTrain);disp (inputBatch)
InputImage ResponseImage  ______________ ______________ { 50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}{50×50双}

设置DnCNN图层

属性创建内置DnCNN网络的层dnCNNLayers(图像处理工具箱)函数。缺省情况下,网络深度(卷积层数)为20。

layers = dnCNNLayers
layers = 1×59带有图层的图层数组:1“InputLayer”图像输入50×50×1图片2 Conv1卷积64 3×3×1步[1]和填充的卷积[1 1 1 1]3‘ReLU1 ReLU ReLU 4 Conv2卷积64 3×3×64旋转步[1]和填充[1 1 1 1]5‘BNorm2批量标准化批量标准化与64个频道6‘ReLU2 ReLU ReLU 7 Conv3卷积64 3×3×64旋转步[1]和填充(1 1 1)8“BNorm3”批量标准化批量标准化与64个频道9“ReLU3”ReLU ReLU 10Conv4卷积64 3×3×64旋转步[1]和填充[1 1 1 1]11的BNorm4批量标准化批量标准化与64个频道12的ReLU4 ReLU ReLU 13 Conv5卷积64 3×3×64旋转步[1]和填充[1 1 1 1]14“BNorm5”批量标准化批量标准化与64个频道15 ' ReLU5 ReLU ReLU 16 Conv6卷积64 3×3×64旋转步[1]和填充[1 1 1 1]17“BNorm6”与64年批量标准化批量正常化渠道18 ' ReLU6 ReLU ReLU 19 Conv7卷积64 3×3×64旋转步[1]和填充[1 1 1 1]20 ' BNorm7批量标准化批量标准化与64个频道21 ' ReLU7 ReLU ReLU 22 Conv8卷积64 3×3×64旋转步[1]和填充[1 1 1 1]23 BNorm8的批量标准化批量标准化与64个频道24的ReLU8 ReLU ReLU 25 Conv9卷积64 3×3×64旋转步[1]和填充[1 1 1 1]26 BNorm9批正常化批规范化与64个频道27 ' ReLU9 ReLU ReLU 28 Conv10卷积64 3×3×64旋转步[1]和填充[1 1 1 1]29“BNorm10”批量标准化批量正常化30 64个频道的ReLU10 ReLU ReLU 31 Conv11卷积64 3×3×64旋转步[1]和填充[1 1 1 1]32“BNorm11”批量标准化批量标准化与64个频道33 ' ReLU11 ReLU ReLU 34 Conv12卷积64 3×3×64旋转步[1]和填充[1 1 11] 35 'BNorm12'批归一化64通道批归一化36 'ReLU12' ReLU ReLU 37 'Conv13' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] 38 'BNorm13'批归一化64通道批归一化39 'ReLU13' ReLU ReLU 40 'Conv14' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] 41 'BNorm14'批归一化64通道批归一化42 'ReLU14' ReLU ReLU 43 'Conv15' Convolution 64 3×3×64 convolutions步[1]和填充[1 1 1 1]44 BNorm15的批量标准化批量标准化与64个频道45‘ReLU15 ReLU ReLU 46 Conv16卷积64 3×3×64旋转步[1]和填充[1 1 1 1]47 BNorm16的批量标准化批量标准化与64个频道48 ' ReLU16 ReLU ReLU 49 Conv17卷积64 3×3×64旋转步[1]和填充[1 1 1 1]50 BNorm17的批量标准化批量标准化51和64个频道的ReLU17 ReLU ReLU 5254 'ReLU18' ReLU ReLU 55 'Conv19' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] 56 'BNorm19' Batch Normalization批量归一化with 64 channels 57 'ReLU19' ReLU ReLU 58 'Conv20' Convolution 1 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] 59 'FinalRegressionLayer'回归输出均方误差

选择培训选项

使用动量随机梯度下降(SGDM)优化训练网络。属性指定SGDM的超参数设置trainingOptions函数。

训练一个深度网络是很耗时的。通过指定高学习率来加速培训。然而,这可能会导致网络的梯度爆炸或不受控制地增长,从而阻止网络成功训练。要将渐变保持在有意义的范围内,请通过设置“GradientThreshold”0.005,并指定“GradientThresholdMethod”使用梯度的绝对值。

maxEpochs = 30;initLearningRate = 0.1;L2reg = 0.0001;batchSize = 64;选项= trainingOptions(“个”...动量= 0.9,...InitialLearnRate = initLearningRate,...LearnRateSchedule =“分段”...GradientThresholdMethod =“绝对值”...GradientThreshold = 0.005,...L2Regularization = l2reg,...MiniBatchSize = batchSize,...MaxEpochs = MaxEpochs,...情节=“训练进步”...Verbose = false);

培训网络

默认情况下,示例加载预训练的DnCNN网络。预训练的网络使您可以执行JPEG块,而无需等待训练完成。

为了训练网络,设置doTraining变量转换为真正的.训练DnCNN网络使用trainNetwork函数。

如果有GPU,可以在GPU上进行训练。使用GPU需要并行计算工具箱™和支持CUDA®的NVIDIA®GPU。有关更多信息,请参见GPU支金宝app持版本(并行计算工具箱).在NVIDIA™Titan X上训练大约需要40个小时。

doTraining =如果doTraining [net,info] = trainNetwork(dsTrain,layers,options);modelDateTime = string(datetime(“现在”格式=“yyyy-MM-dd-HH-mm-ss”));保存(“trainedJPEGDnCNN——”+ modelDateTime +“.mat”“净”);其他的负载(“trainedJPEGDnCNN.mat”);结束

您现在可以使用DnCNN网络从图像中删除JPEG压缩工件。

使用DnCNN网络执行JPEG分块

要使用DnCNN执行JPEG分割,请遵循本例的其余步骤:

  • 用三个不同质量级别的JPEG压缩工件创建示例测试图像。

  • 使用DnCNN网络删除压缩工件。

  • 视觉上比较去块前后的图像。

  • 通过量化压缩和去块图像与未失真参考图像的相似性来评估压缩和去块图像的质量。

创建带有块构件的示例图像

测试数据集,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)

选择一个用于测试JPEG分块网络的测试图像。

testImage =“lighthouse.png”;Ireference = imread(testImage);imshow (Ireference)标题(“未压缩参考图像”

使用JPEG创建三个压缩测试图像质量取值为10、20和50。

imwrite (Ireference fullfile (tempdir“testQuality10.jpg”),“质量”10);imwrite (Ireference fullfile (tempdir“testQuality20.jpg”),“质量”, 20);imwrite (Ireference fullfile (tempdir“testQuality50.jpg”),“质量”, 50);

对压缩图像进行预处理

将图像的压缩版本读入工作区。

I10 = imread(fullfile(tempdir,“testQuality10.jpg”));I20 = imread(fullfile(tempdir,“testQuality20.jpg”));I50 = imread(fullfile(tempdir,“testQuality50.jpg”));

显示压缩图像作为蒙太奇。

蒙太奇({I50,I20,I10},Size=[1 3])jpeg压缩图像,质量因子:50,20和10(从左到右)

回想一下,DnCNN只使用图像的亮度通道进行训练,因为人类的感知对亮度变化比对颜色变化更敏感。控件将jpeg压缩图像从RGB颜色空间转换为YCbCr颜色空间rgb2ycbcr(图像处理工具箱)函数。

I10ycbcr = rgb2ycbcr(I10);I20ycbcr = rgb2ycbcr(I20);I50ycbcr = rgb2ycbcr(I50);

申请DnCNN网络

为了执行网络的向前传递,使用denoiseImage(图像处理工具箱)函数。该函数使用与图像去噪完全相同的训练和测试程序。您可以将JPEG压缩工件视为一种图像噪声。

i10y_predict = denoiseImage(I10ycbcr(:,:,1),net);i20y_predict = denoiseImage(I20ycbcr(:,:,1),net);i50y_predict = denoiseImage(I50ycbcr(:,:,1),net);

色度通道不需要处理。将去噪后的亮度通道与原始色度通道拼接,得到在YCbCr色彩空间中的去噪图像。

i10ycbcr_= cat(3, i10y_, I10ycbcr(:,:,2:3));i20ycbcr_= cat(3, i20y_, I20ycbcr(:,:,2:3));i50ycbcr_= cat(3, i50y_, I50ycbcr(:,:,2:3));

控件将已解锁的YCbCr图像转换为RGB颜色空间ycbcr2rgb(图像处理工具箱)函数。

i10_expected = ycbcr2rgb(i10ycbcr_expected);i20_expected = ycbcr2rgb(i20ycbcr_expected);i50_expected = ycbcr2rgb(i50ycbcr_expected);

显示被屏蔽的图像作为蒙太奇。

蒙太奇({i50_predict, i20_predict},Size=[1 3]) title(“质量因子为50,20和10的去块图像(从左到右)”

为了更好地从视觉上理解这些改进,请检查每个图像中的一个较小区域。使用向量指定感兴趣的区域(ROI)roi格式为[xy宽度高度].元素定义了左上角的x坐标和y坐标,以及ROI的宽度和高度。

ROI = [30 440 100 80];

将压缩图像裁剪到此ROI,并将结果显示为蒙太奇。

i10 = imcrop(i10,roi);i20 = imcrop(i20,roi);i50 = imcrop(i50,roi);蒙太奇({i50 i20 i10},Size=[1 3]) title(质量因子为50,20和10的jpeg压缩图像补丁(从左到右)

将已解锁的图像裁剪到此ROI,并将结果显示为蒙太奇。

i10predict = imcrop(I10_predicted,roi);i20predict = imcrop(i20_predict,roi);i50predict = imcrop(i50_predict,roi);蒙太奇({i50expected, i20expected, i10expected},Size=[1 3]) title(质量因子为50,20和10的去锁图像的补丁(从左到右)

定量比较

通过四个指标来量化被屏蔽图像的质量。您可以使用jpegDeblockingMetrics辅助函数,用于计算质量因子为10、20和50的压缩和去块图像的这些指标。该函数作为支持文件附加到示例中。金宝app

  • 结构相似指数(SSIM)。SSIM评估图像的三个特征的视觉影响:亮度,对比度和结构,相对于参考图像。SSIM值越接近1,说明测试图像与参考图像的一致性越好。这里,参考图像是未失真的原始图像,Ireference,在JPEG压缩之前。看到ssim(图像处理工具箱)有关此指标的更多信息。

  • 峰值信噪比(PSNR)。PSNR值越大,信号相对失真越强。看到psnr值(图像处理工具箱)有关此指标的更多信息。

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

  • 盲/无参考图像空间质量评估(BRISQUE)。BRISQUE使用从带有图像失真的自然场景中训练出来的模型来测量感知图像质量。BRISQUE分数越小,知觉质量越好。看到brisque(图像处理工具箱)有关此指标的更多信息。

jpegDeblockingMetrics (Ireference、I10 I20、I50 I10_predicted, I20_predicted, I50_predicted)
------------------------------------------ SSIM比较  =============== 一块:0.90624 I10_predicted: 0.91286 I20: 0.94904 I20_predicted: 0.95444 I50: 0.97238 I50_predicted: 0.97482  ------------------------------------------ PSNR值比较  =============== 一块:26.6046 I10_predicted: 27.0793 I20: 28.8015 I20_predicted: 29.3378 I50: 31.4512 I50_predicted: 31.8584  ------------------------------------------ NIQE比较  =============== 一块:7.2194 I10_predicted: 3.9469 I20:4.5158 I20_predicted: 3.0681 I50: 2.8874 I50_predicted: 2.4107注:NIQE分数越小,感知质量越好------------------------------------------ BRISQUE比较================== I10: 52.372 I10_predicted: 38.9272 I20: 45.3772 I20_predicted: 30.8993 I50: 27.7093 I50_predicted: 24.3847注:BRISQUE分数越小,感知质量越好

参考文献

张凯,左伟文,陈勇,d.b孟,张磊,“超越高斯去噪:深度CNN图像去噪的残差学习。”IEEE®图像处理汇刊.2017年2月。

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

另请参阅

(图像处理工具箱)|(图像处理工具箱)|(图像处理工具箱)|(图像处理工具箱)|||(图像处理工具箱)

相关的话题