文档

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

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

该示例展示了如何训练DnCNN网络,并提供了一个预训练的DnCNN网络。如果您选择训练DnCNN网络,强烈建议使用具有cuda功能、计算能力3.0或更高的NVIDIA™GPU(需要并行计算工具箱™)。

如果你不想下载训练数据集或训练网络,那么你可以通过输入来加载预训练的DnCNN网络加载(“pretrainedJPEGDnCNN.mat”)在命令行。然后,直接去使用DnCNN网络执行JPEG分块节。

简介

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

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

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

DnCNN网络

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

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

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

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

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

下载培训资料

下载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”“图片”“00”);Exts = {“jpg”bmp格式的“使用”};trainImages = imageDatastore(trainImagesDir,“FileExtensions”ext);

列出训练图像的数量。

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

准备培训数据

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

创建文件夹结构以正确组织培训数据。

originalFileLocation = fullfile(imagesDir,“iaprtc12”“图片”“00”);为训练数据做一个文件夹结构如果~ (fullfile (imagesDir,存在“iaprtc12”“JPEGDeblockingData”“原始”),“dir”) mkdir (fullfile (imagesDir,“iaprtc12”“JPEGDeblockingData”“原始”));结束如果~ (fullfile (imagesDir,存在“iaprtc12”“JPEGDeblockingData”“压缩”),“dir”) mkdir (fullfile (imagesDir,“iaprtc12”“JPEGDeblockingData”“压缩”));结束uncompressedFileLocation = fullfile(imagesDir,“iaprtc12”“JPEGDeblockingData”“原始”);compressedFileLocation = fullfile(imagesDir,“iaprtc12”“JPEGDeblockingData”“压缩”);

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

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

从原始数据中编写原始和压缩的训练图像。

files = dir([originalFileLocation filesep . exe‘* . jpg”]);imNumber = 1;fileIndex = 1:size(files,1) fname = [originalFileLocation filesep files(fileIndex).name];Im = imread(fname);如果Size (im,3) == 3 im = rgb2gray(im);结束index = 1:length(JPEGQuality) imwrite(im,[uncompressedFileLocation filesep num2str(imNumber))“jpg”],“JPEG”“质量”,100) imwrite(im,[compressedFileLocation filesep num2str(imNumber))“jpg”],“JPEG”“质量”,JPEGQuality(index)) imNumber = imNumber + 1;结束结束

定义用于训练的小批量数据存储

一个小批量数据存储用于将训练数据输入网络。此示例定义了一个名为JPEGimagePatchDatastore,作为一种生成增强图像补丁的方便方法,用于训练JPEG分块网络。

JPEGimagePatchDatastore从失真的输入图像中提取斑块,并从原始图像中相应的斑块中计算目标残差。失真的图像块作为网络输入。剩余的补丁是期望的网络输出。每个小批包含128个大小为50 × 50像素的补丁。在训练过程中,每张图像只提取一个迷你批次,所有的补丁都将从图像中的随机位置提取。

batchSize = 128;patchSize = 50;batchesPerImage = 1;Exts = {“jpg”};imdsUncompressed = imageDatastore(uncompressedFileLocation,“FileExtensions”ext);imdsCompressed = imageDatastore(compressedFileLocation,“FileExtensions”ext);ds = JPEGimagePatchDatastore(imdsUncompressed,imdsCompressed,...“MiniBatchSize”batchSize,...“PatchSize”patchSize,...“BatchesPerImage”, batchesPerImage);

在小批数据存储上执行读取操作以查看数据。

inputBatch = read(ds);总结(inputBatch)
变量:jpegPatches: 128×1 cell residuals: 128×1 cell

设置DnCNN图层

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

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

选择培训选项

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

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

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

培训网络

配置训练选项和小批量数据存储后,使用trainNetwork函数。为了训练网络,设置doTraining参数真正的.强烈建议使用具有cuda功能、计算能力3.0或更高版本的NVIDIA™GPU进行培训。

如果你留着doTraining参数在下面的代码中为,则示例返回一个预先训练好的DnCNN网络。

注意:在NVIDIA(TM) Titan X上进行训练大约需要40个小时,根据GPU硬件的不同,训练时间可能更长。

当doTraining为true时,% Training运行doTraining = false;如果doTraining [net, info] = trainNetwork(ds,layers,options);其他的负载(“pretrainedJPEGDnCNN.mat”);结束

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

使用DnCNN网络执行JPEG分块

要使用DnCNN执行JPEG分割,请遵循本示例的其余步骤。该示例的其余部分展示了如何:

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

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

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

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

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

使用DnCNN网络创建样本图像来评估JPEG图像去块的结果。测试数据集,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)

选择其中一个图像作为JPEG分块的参考图像。您可以选择使用自己的未压缩图像作为参考图像。

指数= 7;从测试映像数据存储中读取的映像的索引Ireference = readimage(testImages, index);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},“大小”,[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_predicted、I20_predicted I10_predicted},“大小”,[1 3])质量因子: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},“大小”,[1 3])质量因子为50,20和10的jpeg压缩图像补丁(从左到右)

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

i10predict = imcrop(I10_predicted,roi);i20predict = imcrop(i20_predict,roi);i50predict = imcrop(i50_predict,roi);蒙太奇({i50predicted、i20predicted i10predicted},“大小”,[1 3])质量因子:50,20和10(从左到右)的去锁图像的补丁

定量比较

通过四个指标来量化被屏蔽图像的质量。您可以使用displayJPEGResults辅助函数,用于计算质量因子为10、20和50的压缩和去块图像的这些指标。

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

  • 峰值信噪比(PSNR)。PNSR值越大,信号相对失真越强。看到psnr值有关此指标的更多信息。

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

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

displayJPEGResults (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.0989 I10_predicted: 3.9334 I20:4.5065 I20_predicted: 3.0699 I50: 2.8866 I50_predicted: 2.4109注:NIQE分数越小,感知质量越好------------------------------------------ BRISQUE比较================== I10: 52.2731 I10_predicted: 38.9688 I20: 45.5237 I20_predicted: 30.9583 I50: 27.7386 I50_predicted: 24.3889注:BRISQUE分数越小,感知质量越好

总结

这个例子展示了如何创建和训练DnCNN网络,然后使用该网络来减少图像中的JPEG压缩工件。以下是训练网络的步骤:

  • 下载培训数据。

  • 通过将原始图像写入具有不同级别压缩的JPEG文件格式来创建训练图像。

  • 定义一个自定义的小批数据存储,称为JPEGimagePatchDatastore,从输入压缩图像中提取patch,并从原始图像中相应的patch中计算目标残差。该数据存储用于向网络提供训练数据。

  • 属性创建DnCNN网络的层dnCNNLayers函数。

  • 指定培训选项。

  • 训练网络使用trainNetwork函数。

在训练DnCNN网络或加载预训练的DnCNN网络后,该示例以三个质量值压缩测试图像,然后使用网络去除压缩工件。

参考文献

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

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

另请参阅

|||||

相关的话题

这个话题有用吗?