Одно изображение Суперразрешения используя глубокое обучение

Этот пример показывает, как оценить изображение с высоким разрешением из изображения с низким разрешением с помощью очень глубокой нейронной сети суперразрешения (VDSR).

Суперразрешение - это процесс создания изображений с высоким разрешением из изображений с низким разрешением. Этот пример рассматривает одно изображение суперразрешения (SISR), где цель состоит в том, чтобы восстановить одно изображение высокого разрешения из одного изображения низкого разрешения. SISR является сложным, потому что высокочастотное содержимое изображения обычно не может быть восстановлено из изображения низкого разрешения. Без высокочастотной информации качество изображения с высоким разрешением ограничено. Кроме того, SISR является плохо поставленной проблемой, поскольку одно изображение с низким разрешением может давать несколько возможных изображений с высоким разрешением.

Для выполнения SISR было предложено несколько методов, включая алгоритмы глубокого обучения. Этот пример исследует один алгоритм глубокого обучения для SISR, называемый очень глубоким суперразрешение (VDSR) [1].

Сеть VDSR

VDSR является сверточной архитектурой нейронной сети, предназначенной для выполнения одиночных суперразрешений изображений [1]. Сеть VDSR изучает отображение между изображениями с низким и высоким разрешением. Это отображение возможно, потому что изображения с низким разрешением и высоким разрешением имеют сходное содержимое изображения и отличаются, в основном, высокочастотными деталями.

VDSR использует стратегию остаточного обучения, что означает, что сеть учится оценивать остаточное изображение. В контексте суперразрешения остаточное изображение является различием между ссылкой изображением с высоким разрешением и изображением с низким разрешением, которое было увеличено с помощью бикубической интерполяции, чтобы соответствовать размеру ссылки изображения. Остаточное изображение содержит информацию о высокочастотных деталях изображения.

Сеть VDSR обнаруживает остаточное изображение по яркости цветного изображения. Канал яркости изображения, Y, представляет яркость каждого пикселя через линейную комбинацию значений красного, зеленого и синего пикселей. Напротив, два канала цветности изображения, Cb и Cr, являются различными линейными комбинациями красных, зеленых и синих пиксельных значений, которые представляют информацию о цветовой разности. VDSR обучается, используя только канал яркости, потому что восприятие человека более чувствительно к изменениям яркости, чем к изменениям цвета.

Если Yhighres яркость изображения с высоким разрешением и Ylowres - яркость изображения низкого разрешения, которое было увеличено с помощью бикубической интерполяции, тогда вход в сеть VDSR Ylowres и сеть учится предсказывать Yresidual=Yhighres-Ylowres из обучающих данных.

После того, как сеть VDSR научится оценивать остаточное изображение, можно восстановить изображения с высоким разрешением путем добавления оцененного остаточного изображения к увеличенному изображению с низким разрешением, затем преобразования изображения назад в цветовое пространство RGB.

Коэффициент шкалы связывает размер ссылки изображения с размером изображения с низким разрешением. Когда коэффициент шкалы увеличивается, SISR становится более плохо представленным, потому что изображение низкого разрешения теряет больше информации о содержимом высокочастотного изображения. VDSR решает эту задачу с помощью большого рецептивного поля. Этот пример обучает сеть VDSR с несколькими масштабными факторами с помощью увеличения шкалы. Увеличение шкалы улучшает результаты при больших масштабных факторах, потому что сеть может использовать контекст изображения из меньших масштабных коэффициентов. Кроме того, сеть VDSR может обобщаться, чтобы принимать изображения с нецелочисленными масштабными факторами.

Загрузка обучающих и тестовых данных

Загрузите IAPR TC-12 Benchmark, который состоит из 20 000 все еще естественных изображений [2]. Набор данных включает фотографии людей, животных, городов и многое другое. Размер файла данных составляет ~ 1,8 ГБ. Если вы не хотите загружать обучающие данные набор, то можно загрузить предварительно обученную сеть VDSR, набрав load('trainedVDSR-Epoch-100-ScaleFactors-234.mat'); в командной строке. Затем перейдите непосредственно к разделу «Выполнение суперразрешения одиночного изображения с использованием сети VDSR» в этом примере.

Используйте функцию helper, downloadIAPRTC12Data, для загрузки данных. Эта функция присоединена к примеру как вспомогательный файл.

imagesDir = tempdir;
url = 'http://www-i6.informatik.rwth-aachen.de/imageclef/resources/iaprtc12.tgz';
downloadIAPRTC12Data(url,imagesDir);

Этот пример обучит сеть с небольшим подмножеством данных IAPR TC-12 Benchmark. Загрузите обучающие данные imageCLEF. Все изображения являются 32-битными цветными изображениями JPEG.

trainImagesDir = fullfile(imagesDir,'iaprtc12','images','02');
exts = {'.jpg','.bmp','.png'};
pristineImages = imageDatastore(trainImagesDir,'FileExtensions',exts);

Перечислите количество обучающих изображений.

numel(pristineImages.Files)
ans = 616

Подготовка обучающих данных

Чтобы создать набор обучающих данных, сгенерируйте пары изображений, состоящих из восходящих изображений и соответствующих остаточных изображений.

Изображения с повышенной дискретизацией хранятся на диске в виде файлов MAT в директории upsampledDirName. Вычисленные остаточные изображения, представляющие сетевые отклики, хранятся на диске в виде файлов MAT в директории residualDirName. Файлы MAT хранятся как тип данных double для большей точности при обучении сети.

upsampledDirName = [trainImagesDir filesep 'upsampledImages'];
residualDirName = [trainImagesDir filesep 'residualImages'];

Используйте функцию helper createVDSRTrainingSet для предварительной обработки обучающих данных. Эта функция присоединена к примеру как вспомогательный файл.

Функция helper выполняет эти операции для каждого первозданного изображения в trainImages:

  • Преобразуйте изображение в цветовое пространство YCbCr

  • Уменьшите размер канала яркости (Y) различными масштабными факторами, чтобы создать выборку изображений с низким разрешением, затем измените размер изображений до исходного размера с помощью бикубической интерполяции

  • Вычислите различие между первозданным и измененным размерами изображений.

  • Сохраните измененные и остаточные изображения на диск.

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

Определите трубопровод предварительной обработки для набора обучающих данных

В этом примере сетевые входы являются изображениями с низким разрешением, которые были увеличены с помощью бикубической интерполяции. Желаемыми сетевыми характеристиками являются остаточные изображения. Создайте изображение datastore под названием upsampledImages из набора входных файлов изображений. Создайте изображение datastore под названием residualImages из набора вычисленных файлов остаточных изображений. Оба хранилища данных требуют вспомогательной функции, matRead, для чтения данных изображения из файлов изображений. Эта функция присоединена к примеру как вспомогательный файл.

upsampledImages = imageDatastore(upsampledDirName,'FileExtensions','.mat','ReadFcn',@matRead);
residualImages = imageDatastore(residualDirName,'FileExtensions','.mat','ReadFcn',@matRead);

Создайте imageDataAugmenter который задает параметры увеличения данных. Используйте увеличение данных во время обучения, чтобы изменить обучающие данные, что эффективно увеличивает объем доступных обучающих данных. Здесь augmenter задает случайное вращение на 90 степени и случайные отражения в направлении x.

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

Создайте randomPatchExtractionDatastore (Image Processing Toolbox), который выполняет рандомизированное извлечение закрашенной фигуры из хранилищ данных с повышенной и остаточной дискретизацией изображений. Извлечение закрашенной фигуры - это процесс извлечения большого набора небольших закрашенных фигур для изображений, или плиток, из одного большего изображения. Этот тип увеличения данных часто используется в задачах регрессии изображение-изображение, где многие сетевые архитектуры могут быть обучены при очень малых размерах входных изображений. Это означает, что из каждого полноразмерного изображения в исходном наборе обучающих данных может быть извлечено большое количество закрашенных фигур, что значительно увеличивает размер набора обучающих данных.

patchSize = [41 41];
patchesPerImage = 64;
dsTrain = randomPatchExtractionDatastore(upsampledImages,residualImages,patchSize, ...
    "DataAugmentation",augmenter,"PatchesPerImage",patchesPerImage);

Получившийся datastore, dsTrain, предоставляет мини-пакеты данных в сеть в каждую итерацию эпохи. Предварительный просмотр результатов чтения из datastore.

inputBatch = preview(dsTrain);
disp(inputBatch)
      InputImage      ResponseImage 
    ______________    ______________

    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}
    {41×41 double}    {41×41 double}

Настройка слоев VDSR

Этот пример определяет сеть VDSR, используя 41 отдельный слой из Deep Learning Toolbox™, включая:

  • imageInputLayer - Входной слой изображения

  • convolution2dLayer - 2-D слой свертки для сверточных нейронных сетей

  • reluLayer - Слой выпрямленного линейного модуля (ReLU)

  • regressionLayer - Регрессионный выходной слой для нейронной сети

Первый слой, imageInputLayer, работает с закрашенными фигурами изображений. Размер закрашенной фигуры основан на сетевом приемном поле, которое является пространственной областью изображения, которая влияет на ответ самого верхнего слоя в сети. В идеале сетевое поле приема совпадает с размером изображения, так что поле может видеть все высокоуровневые функции в изображении. В этом случае для сети с D сверточными слоями рецептивное поле является (2D + 1) -by- (2D + 1).

VDSR имеет 20 сверточных слоев, поэтому приемное поле и размер закрашенной фигуры изображения являются 41 на 41. Входной слой изображения принимает изображения с одним каналом, потому что VDSR обучается, используя только канал яркости.

networkDepth = 20;
firstLayer = imageInputLayer([41 41 1],'Name','InputLayer','Normalization','none');

За входным слоем изображения следует 2-D сверточный слой, который содержит 64 фильтров размера 3 на 3. Размер мини-пакета определяет количество фильтров. Обнулите входы каждого сверточного слоя так, чтобы карты функций оставались такими же размерами, как вход после каждой свертки. Метод [3] инициализирует веса к случайным значениям, так что в нейрон обучении есть асимметрия. Каждый сверточный слой сопровождается слоем ReLU, который вводит нелинейность в сети.

convLayer = convolution2dLayer(3,64,'Padding',1, ...
    'WeightsInitializer','he','BiasInitializer','zeros','Name','Conv1');

Задайте слой ReLU.

relLayer = reluLayer('Name','ReLU1');

Средние слои содержат 18 чередующихся сверточных и выпрямленных линейных единичных слоев. Каждый сверточный слой содержит 64 фильтра размера 3 на 3 на 64, где фильтр воздействует на пространственную область 3 на 3 через 64 канала. Как и прежде, слой ReLU следует за каждым сверточным слоем.

middleLayers = [convLayer relLayer];
for layerNumber = 2:networkDepth-1
    convLayer = convolution2dLayer(3,64,'Padding',[1 1], ...
        'WeightsInitializer','he','BiasInitializer','zeros', ...
        'Name',['Conv' num2str(layerNumber)]);
    
    relLayer = reluLayer('Name',['ReLU' num2str(layerNumber)]);
    middleLayers = [middleLayers convLayer relLayer];    
end

Предпоследний слой - сверточный слой с единственным фильтром размера 3 на 3 на 64, который восстанавливает изображение.

convLayer = convolution2dLayer(3,1,'Padding',[1 1], ...
    'WeightsInitializer','he','BiasInitializer','zeros', ...
    'NumChannels',64,'Name',['Conv' num2str(networkDepth)]);

Последний слой является регрессионным слоем вместо слоя ReLU. Регрессионный слой вычисляет среднюю квадратную ошибку между остаточным изображением и сетевым предсказанием.

finalLayers = [convLayer regressionLayer('Name','FinalRegressionLayer')];

Объедините все слои, чтобы сформировать сеть VDSR.

layers = [firstLayer middleLayers finalLayers];

Также можно использовать vdsrLayers вспомогательная функция для создания слоев VDSR. Эта функция присоединена к примеру как вспомогательный файл.

layers = vdsrLayers;

Настройка опций обучения

Обучите сеть с помощью стохастического градиентного спуска с оптимизацией импульса (SGDM). Задайте установки гиперпараметров для SGDM при помощи trainingOptions функция. Скорость обучения первоначально 0.1 и уменьшались в 10 раз каждые 10 эпох. Тренируйтесь на 100 эпох.

Обучение глубокой сети занимает много времени. Ускорите обучение, задав высокую скорость обучения. Однако это может заставить градиенты сети взрываться или расти бесконтрольно, препятствуя успешному обучению сети. Чтобы сохранить градиенты в значимой области значений, включите усечение градиента путем определения 'GradientThreshold' как 0.01, и задайте 'GradientThresholdMethod' для использования L2-norm градиентов.

maxEpochs = 100;
epochIntervals = 1;
initLearningRate = 0.1;
learningRateFactor = 0.1;
l2reg = 0.0001;
miniBatchSize = 64;
options = trainingOptions('sgdm', ...
    'Momentum',0.9, ...
    'InitialLearnRate',initLearningRate, ...
    'LearnRateSchedule','piecewise', ...
    'LearnRateDropPeriod',10, ...
    'LearnRateDropFactor',learningRateFactor, ...
    'L2Regularization',l2reg, ...
    'MaxEpochs',maxEpochs, ...
    'MiniBatchSize',miniBatchSize, ...
    'GradientThresholdMethod','l2norm', ...
    'GradientThreshold',0.01, ...
    'Plots','training-progress', ...
    'Verbose',false);

Обучите сеть

По умолчанию пример загружает предварительно обученную версию сети VDSR, которая была обучена суперразрешать изображения для масштабных коэффициентов 2, 3 и 4. Предварительно обученная сеть позволяет вам выполнить суперразрешение тестовых изображений, не дожидаясь завершения обучения.

Для обучения сети VDSR установите doTraining переменная в следующем коде, для true. Обучите сеть с помощью trainNetwork функция.

Обучите на графическом процессоре, если он доступен. Для использования GPU требуется Parallel Computing Toolbox™ и графический процессор с поддержкой CUDA ® NVIDIA ®. Для получения дополнительной информации смотрите Поддержку GPU by Release (Parallel Computing Toolbox). Обучение занимает около 6 часов на NVIDIA Titan X.

doTraining = false;
if doTraining
    net = trainNetwork(dsTrain,layers,options);
    modelDateTime = string(datetime('now','Format',"yyyy-MM-dd-HH-mm-ss"));
    save(strcat("trainedVDSR-",modelDateTime,"-Epoch-",num2str(maxEpochs),"-ScaleFactors-234.mat"),'net');
else
    load('trainedVDSR-Epoch-100-ScaleFactors-234.mat');
end

Выполните Суперразрешение с одним изображением, используя сеть VDSR

Чтобы выполнить одно суперразрешение изображения (SISR) с помощью сети VDSR, выполните оставшиеся шаги этого примера. Остальная часть примера показывает, как:

  • Создайте выборку изображения низкого разрешения из эталонного изображения высокого разрешения.

  • Выполните SISR на изображении низкого разрешения с помощью бикубической интерполяции, традиционного решения для обработки изображений, которое не полагается на глубокое обучение.

  • Выполните SISR на изображении низкого разрешения с помощью нейронной сети VDSR.

  • Визуально сравните восстановленные изображения высокого разрешения с помощью бикубической интерполяции и VDSR.

  • Оцените качество сверхразрешенных изображений путем количественной оценки подобия изображений ссылки изображению с высоким разрешением.

Создайте выборку изображения с низким разрешением

Создайте изображение низкого разрешения, которое будет использоваться для сравнения результатов суперразрешения с помощью глубокого обучения с результатом с помощью традиционных методов обработки изображений, таких как бикубическая интерполяция. Набор тестовых данных, testImages, содержит 21 неискаженное изображение, поставленное в Image Processing Toolbox™. Загрузите изображения в imageDatastore.

exts = {'.jpg','.png'};
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,'toolbox','images','imdata') filesep];
filePathNames = strcat(filePath,fileNames);
testImages = imageDatastore(filePathNames,'FileExtensions',exts);

Отобразите тестовые изображения как монтаж.

montage(testImages)

Выберите одно из изображений для использования в качестве эталонного изображения для суперразрешения. Вы можете опционально использовать ваше собственное изображение высокого разрешения в качестве ссылки изображения.

indx = 1; % Index of image to read from the test image datastore
Ireference = readimage(testImages,indx);
Ireference = im2double(Ireference);
imshow(Ireference)
title('High-Resolution Reference Image')

Создайте версию эталонного изображения с низким разрешением при помощи imresize (Image Processing Toolbox) с коэффициентом масштабирования 0,25. Высокочастотные компоненты изображения теряются во время уменьшения масштаба.

scaleFactor = 0.25;
Ilowres = imresize(Ireference,scaleFactor,'bicubic');
imshow(Ilowres)
title('Low-Resolution Image')

Улучшите разрешение изображения с помощью бикубической интерполяции

Стандартным способом увеличить разрешение изображения без глубокого обучения является использование бикубической интерполяции. Увеличьте масштаб изображения низкого разрешения с помощью бикубической интерполяции, чтобы полученное изображение высокого разрешения было такого же размера, как и ссылка изображение.

[nrows,ncols,np] = size(Ireference);
Ibicubic = imresize(Ilowres,[nrows ncols],'bicubic');
imshow(Ibicubic)
title('High-Resolution Image Obtained Using Bicubic Interpolation')

Улучшите разрешение изображений с помощью предварительно обученной сети VDSR

Напомним, что VDSR обучается с использованием только канала яркости изображения, потому что восприятие человека более чувствительно к изменениям яркости, чем к изменениям цвета.

Преобразуйте изображение низкого разрешения из цветового пространства RGB в яркость (Iy) и цветность (Icb и Icr) каналы при помощи rgb2ycbcr (Image Processing Toolbox) функция.

Iycbcr = rgb2ycbcr(Ilowres);
Iy = Iycbcr(:,:,1);
Icb = Iycbcr(:,:,2);
Icr = Iycbcr(:,:,3);

Усильте яркость и два канала цветности с помощью бикубической интерполяции. Усиленные каналы цветности, Icb_bicubic и Icr_bicubic, не требуют дальнейшей обработки.

Iy_bicubic = imresize(Iy,[nrows ncols],'bicubic');
Icb_bicubic = imresize(Icb,[nrows ncols],'bicubic');
Icr_bicubic = imresize(Icr,[nrows ncols],'bicubic');

Передайте усиленный компонент яркости, Iy_bicubic, через обученную сеть VDSR. Наблюдайте за activations от последнего слоя (регрессионного слоя). Выходы сети являются желаемым остаточным изображением.

Iresidual = activations(net,Iy_bicubic,41);
Iresidual = double(Iresidual);
imshow(Iresidual,[])
title('Residual Image from VDSR')

Добавьте остаточное изображение к компоненту повышенной яркости, чтобы получить компонент яркости VDSR с высоким разрешением.

Isr = Iy_bicubic + Iresidual;

Конкатенируйте компонент яркости VDSR с высоким разрешением с увеличенными цветовыми компонентами. Преобразуйте изображение в цветовое пространство RGB при помощи ycbcr2rgb (Image Processing Toolbox) функция. Результатом является окончательное цветное изображение высокого разрешения с использованием VDSR.

Ivdsr = ycbcr2rgb(cat(3,Isr,Icb_bicubic,Icr_bicubic));
imshow(Ivdsr)
title('High-Resolution Image Obtained Using VDSR')

Визуальное и количественное сравнение

Чтобы получить лучшее визуальное понимание изображений с высоким разрешением, исследуйте небольшую область внутри каждого изображения. Задайте видимую область (ROI) с помощью вектора roi в формате [x y ширина высота]. Элементы определяют координаты x и y верхнего левого угла, ширину и высоту информация только для чтения.

roi = [320 30 480 400];

Обрезайте изображения с высоким разрешением до этого информация только для чтения и отобразите результат как montage. Изображение VDSR имеет более четкие детали и более резкие ребра, чем изображение высокого разрешения, созданное с помощью бикубической интерполяции.

montage({imcrop(Ibicubic,roi),imcrop(Ivdsr,roi)})
title('High-Resolution Results Using Bicubic Interpolation (Left) vs. VDSR (Right)');

Используйте метрики качества изображений, чтобы количественно сравнить изображение высокого разрешения с помощью бикубической интерполяции с изображением VDSR. Эталонным изображением является исходное изображение высокого разрешения, Ireference, перед подготовкой выборки изображения с низким разрешением.

Измерьте отношение пикового сигнала к шуму (PSNR) каждого изображения относительно ссылки изображения. Большие значения PSNR обычно указывают на лучшее качество изображения. См. psnr (Image Processing Toolbox) для получения дополнительной информации об этой метрике.

bicubicPSNR = psnr(Ibicubic,Ireference)
bicubicPSNR = 38.4747
vdsrPSNR = psnr(Ivdsr,Ireference)
vdsrPSNR = 39.2346

Измерьте индекс структурного подобия (SSIM) каждого изображения. SSIM оценивает визуальное влияние трех характеристик изображения: яркость, контрастность и структуру, по сравнению с ссылкой изображением. Чем ближе значение SSIM к 1, тем лучше тестовое изображение согласуется с ссылкой изображением. См. ssim (Image Processing Toolbox) для получения дополнительной информации об этой метрике.

bicubicSSIM = ssim(Ibicubic,Ireference)
bicubicSSIM = 0.9861
vdsrSSIM = ssim(Ivdsr,Ireference)
vdsrSSIM = 0.9874

Измерьте качество перцептивного изображения с помощью Naturalness Image Quality Evaluator (NIQE). Меньшие счета NIQE указывают на лучшее качество восприятия. См. niqe (Image Processing Toolbox) для получения дополнительной информации об этой метрике.

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

Вычислите средние значения PSNR и SSIM для всего набора тестовых изображений для факторов шкалы 2, 3 и 4. Для простоты можно использовать функцию helper, superResolutionMetrics, для вычисления средних метрик. Эта функция присоединена к примеру как вспомогательный файл.

scaleFactors = [2 3 4];
superResolutionMetrics(net,testImages,scaleFactors);
Results for Scale factor 2

Average PSNR for Bicubic = 31.809683
Average PSNR for VDSR = 31.921784
Average SSIM for Bicubic = 0.938194
Average SSIM for VDSR = 0.949404

Results for Scale factor 3

Average PSNR for Bicubic = 28.170441
Average PSNR for VDSR = 28.563952
Average SSIM for Bicubic = 0.884381
Average SSIM for VDSR = 0.895830

Results for Scale factor 4

Average PSNR for Bicubic = 27.010839
Average PSNR for VDSR = 27.837260
Average SSIM for Bicubic = 0.861604
Average SSIM for VDSR = 0.877132

VDSR имеет лучшие метрические счета, чем бикубическая интерполяция для каждого масштабного фактора.

Ссылки

[1] Ким, Дж., Дж. К. Ли и К. М. Ли. «Точное суперразрешение изображений с использованием очень глубоких сверточных сетей». Материалы IEEE ® Conference on Компьютерное Зрение and Pattern Recognition. 2016, стр. 1646-1654.

[2] Грубингер, М., П. Клаф, Х. Мюллер и Т. Дезелаерс. «IAPR TC-12 Benchmark: A New Evaluation Resource for Visual Information Systems». Сведения о языковых ресурсах OntoImage 2006 для поиска изображений на основе содержимого. Генуя, Италия. Том 5, май 2006, стр. 10.

[3] He, K., X. Zhang, S. Ren, and J. Sun. «Delving Deep Into Rectifiers: Overpassing Human-Level Performance on ImageNet Classification». Материалы Международной конференции IEEE по компьютерному зрению, 2015, стр. 1026-1034.

См. также

| | | | | |

Похожие темы