В этом примере показано, как MATLAB ® и Image Processing Toolbox™ могут выполнять общие виды увеличения изображений как часть рабочих процессов глубокого обучения.
Функции Image Processing Toolbox позволяют вам реализовать общие стили увеличения изображений. Этот пример демонстрирует пять распространенных типов преобразований:
Затем пример показывает, как применить увеличение к данным изображений в хранилищах данных с помощью комбинации нескольких типов преобразований.
Можно использовать дополненные обучающие данные для обучения сети. Пример настройки сети с использованием дополненных изображений см. в разделе «Подготовка Datastore к регрессии изображение-изображение».
Чтение и отображение примера изображения. Чтобы сравнить эффект увеличения изображений разных типов, каждое преобразование использует одно и то же входное изображение.
imOriginal = imread('kobi.png');
imshow(imOriginal)
The randomAffine2d
(Image Processing Toolbox) функция создает рандомизированное 2-D аффинное преобразование из комбинации вращения, перемещения, шкалы (изменения размера), отражения и сдвига. Можно задать, какие преобразования включать и область значений параметров преобразования. Если вы задаете область значений как двухэлементный числовой вектор, то randomAffine2d
выбирает значение параметра из равномерного распределения вероятностей за заданный интервал. Для дополнительного управления областью значений значений параметров можно задать область значений с помощью указателя на функцию.
Управляйте пространственными границами и разрешением искривленного изображения, созданного imwarp
(Image Processing Toolbox) при помощи affineOutputView
(Image Processing Toolbox) функция.
Создайте рандомизированное преобразование поворота, которое вращает вход изображение на угол, выбранный случайным образом из области значений [-45, 45] степеней.
tform = randomAffine2d('Rotation',[-45 45]); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView); imshow(imAugmented)
Создайте преобразование преобразования, которое смещает входное изображение горизонтально и вертикально на расстояние, выбранное случайным образом из области значений [-50, 50] пикселей.
tform = randomAffine2d('XTranslation',[-50 50],'YTranslation',[-50 50]); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView); imshow(imAugmented)
Создайте шкалу преобразование, которое изменяет размер входа изображения с помощью коэффициента шкалы, выбранного случайным образом из области значений [1.2, 1.5]. Это преобразование изменяет размер изображения на тот же коэффициент в горизонтальном и вертикальном направлениях.
tform = randomAffine2d('Scale',[1.2,1.5]); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView); imshow(imAugmented)
Создайте преобразование отражения, которое переворачивает вход изображение с 50% вероятностью в каждой размерности.
tform = randomAffine2d('XReflection',true,'YReflection',true); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView); imshow(imAugmented)
Создайте горизонтальное преобразование сдвига с углом сдвига, выбранным случайным образом из области значений [-30, 30].
tform = randomAffine2d('XShear',[-30 30]); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView); imshow(imAugmented)
В предыдущих преобразованиях область значений параметров преобразования задавалась двухэлементными числовыми векторами. Для получения дополнительной информации о области значений параметров преобразования задайте указатель на функцию вместо числового вектора. Указатель на функцию не принимает входных параметров и приводит к допустимому значению для каждого параметра.
Для примера этот код выбирает угол поворота из дискретного набора углов поворота 90 степеней.
angles = 0:90:270; tform = randomAffine2d('Rotation',@() angles(randi(4))); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView); imshow(imAugmented)
Когда вы деформируете изображение с помощью геометрического преобразования, пиксели в выходном изображении могут отображаться в положение за пределами входного изображения. В этом случае imwarp
присваивает значение заливки этим пикселям на выходном изображении. По умолчанию imwarp
выбирает черное в качестве значения заливки. Можно изменить значение заливки, задав 'FillValues'
аргумент пары "имя-значение".
Создайте случайное преобразование поворота, затем примените преобразование и задайте значение серой заливки.
tform = randomAffine2d('Rotation',[-45 45]); outputView = affineOutputView(size(imOriginal),tform); imAugmented = imwarp(imOriginal,tform,'OutputView',outputView,'FillValues',[128 128 128]); imshow(imAugmented)
Чтобы создать выходные изображения необходимого размера, используйте randomWindow2d
(Image Processing Toolbox) и centerCropWindow2d
(Image Processing Toolbox) функции. Будьте осторожны, чтобы выбрать окно, которое включает требуемое содержимое в изображение.
Задайте требуемый размер обрезанной области как вектор с 2 элементами вида [высота, ширина].
targetSize = [200,100];
Обрезать изображение до целевого размера из центра изображения.
win = centerCropWindow2d(size(imOriginal),targetSize); imCenterCrop = imcrop(imOriginal,win); imshow(imCenterCrop)
Обрезать изображение до целевого размера из случайного расположения на изображении.
win = randomWindow2d(size(imOriginal),targetSize); imRandomCrop = imcrop(imOriginal,win); imshow(imRandomCrop)
Вы можете случайным образом настроить оттенок, насыщение, яркость и контрастность цветного изображения при помощи jitterColorHSV
(Image Processing Toolbox) функция. Можно задать, какие цветовые преобразования включены, и область значений параметров преобразования.
Можно случайным образом настроить яркость и контрастность полутоновых изображений с помощью базовых математических операций.
Hue задает оттенок цвета или положение цвета на цветовом колесе. Поскольку оттенок варьируется от 0 до 1, цвета варьируются от красного до желтого, зеленого, голубого, синего, фиолетового, пурпурного и обратно к красному. Дрожь оттенка смещает видимый оттенок цветов в изображении.
Отрегулируйте оттенок входного изображения небольшим положительным смещением, выбранным случайным образом из области значений [0,05, 0,15]. Красные цвета теперь выглядят более оранжевыми или желтыми, оранжевые - желтыми или зелеными и так далее.
imJittered = jitterColorHSV(imOriginal,'Hue',[0.05 0.15]);
montage({imOriginal,imJittered})
Насыщение - это чистота цвета. Поскольку насыщение изменяется от 0 до 1, оттенки варьируются от серого (что указывает на смесь всех цветов) до одного чистого цвета. Дрожание насыщения смещает насколько тусклые или яркие цвета.
Настройте насыщение входного изображения смещением, выбранным случайным образом из области значений [-0,4, -0,1]. Цвета в выходном изображении выглядят более приглушенными, как и ожидалось при уменьшении насыщения.
imJittered = jitterColorHSV(imOriginal,'Saturation',[-0.4 -0.1]);
montage({imOriginal,imJittered})
Яркость - это количество оттенка. Поскольку яркость изменяется от 0 до 1, цвета переходят от черного к белому. Джиттер яркости смещает темноту и легкость входного изображения.
Отрегулируйте яркость входного изображения смещением, выбранным случайным образом из области значений [-0.3, -0.1]. Изображение выглядит темнее, как и ожидалось, когда яркость уменьшается.
imJittered = jitterColorHSV(imOriginal,'Brightness',[-0.3 -0.1]);
montage({imOriginal,imJittered})
Контрастный джиттер случайным образом настраивает различие между самыми темными и самыми яркими областями на вход изображении.
Настройте контрастность входа изображения на коэффициент шкалы, выбранный случайным образом из области значений [1.2, 1.4]. Контраст увеличивается, так что тени становятся темнее, а подсветки становятся ярче.
imJittered = jitterColorHSV(imOriginal,'Contrast',[1.2 1.4]);
montage({imOriginal,imJittered})
Можно применить рандомизированную яркость и контрастный дрожание к полутоновым изображениям с помощью базовых математических операций.
Преобразуйте образец изображения в полутоновый. Задайте коэффициент случайной контрастной шкалы в области значений [0,8, 1] и смещение случайной яркости в области значений [-0,15, 0,15]. Умножьте изображение на контрастный масштабный коэффициент, затем добавьте смещение яркости.
imGray = rgb2gray(im2double(imOriginal)); contrastFactor = 1-0.2*rand; brightnessOffset = 0.3*(rand-0.5); imJittered = imGray.*contrastFactor + brightnessOffset; imJittered = im2uint8(imJittered); montage({imGray,imJittered})
Один тип увеличения цвета случайным образом отбрасывает информацию о цвете из изображения RGB с сохранением количества каналов, ожидаемых сетью. Этот код показывает преобразование «случайный полутоновый», при котором изображение RGB случайным образом преобразуется с 80% вероятностью в трехканальное выходное изображение, где R = = G = = B.
desiredProbability = 0.8; if rand <= desiredProbability imJittered = repmat(rgb2gray(imOriginal),[1 1 3]); end imshow(imJittered)
Используйте transform
функция для применения любой комбинации функций Image Processing Toolbox к входным изображениям. Добавление шума и размытия являются двумя общими операциями обработки изображений, используемыми в применениях глубокого обучения.
Чтобы применить синтетический шум к входу изображению, используйте imnoise
(Image Processing Toolbox) функция. Можно задать, какую модель шума использовать, такую как Гауссов, Пуассон, соль и перец и мультипликативный шум. Можно также задать силу шума.
imSaltAndPepperNoise = imnoise(imOriginal,'salt & pepper',0.1); imGaussianNoise = imnoise(imOriginal,'gaussian'); montage({imSaltAndPepperNoise,imGaussianNoise})
Чтобы применить рандомизированное Гауссово размытие к изображению, используйте imgaussfilt
(Image Processing Toolbox) функция. Можно задать величину сглаживания.
sigma = 1+5*rand; imBlurred = imgaussfilt(imOriginal,sigma); imshow(imBlurred)
В практических задачах глубокого обучения конвейер увеличения изображения обычно объединяет несколько операций. Datastores - удобный способ чтения и увеличения наборов изображений.
Datastores - удобный способ чтения и увеличения наборов изображений. В этом разделе примера показано, как задать трубопроводы увеличения данных, которые увеличивают хранилища данных в контексте задач классификации обучающих изображений и регрессии изображений.
Во-первых, создайте imageDatastore
который содержит необработанные изображения. image datastore в этом примере содержит цифровые изображения с метками.
digitDatasetPath = fullfile(matlabroot,'toolbox','nnet', ... 'nndemos','nndatasets','DigitDataset'); imds = imageDatastore(digitDatasetPath, ... 'IncludeSubfolders',true, ... 'LabelSource','foldernames'); imds.ReadSize = 6;
В классификации изображений классификатор должен узнать, что случайным образом измененная версия изображения все еще представляет один и тот же класс изображения. Чтобы увеличить данные для классификации изображений, достаточно увеличить входные изображения, оставив соответствующие категориальные метки неизменными.
Увеличение изображений в pristine image datastore со случайным Гауссовым размытием, сольным и перцовым шумом и рандомизированной шкалой и вращением. Эти операции определены в вспомогательной функции classificationAugmentationPipeline
в конце этого примера. Примените увеличение данных к обучающим данным при помощи transform
функция.
dsTrain = transform(imds,@classificationAugmentationPipeline,'IncludeInfo',true);
Визуализируйте выборку выхода, поступающей из дополненного трубопровода.
dataPreview = preview(dsTrain);
montage(dataPreview(:,1))
title("Augmented Images for Image Classification")
Увеличение изображения для регрессии изображение-изображение сложнее, потому что вы должны применить идентичные геометрические преобразования к входу и ответным изображениям. Ассоциируйте пары входных и ответных изображений при помощи combine
функция. Преобразуйте одно или оба изображения в каждой паре с помощью transform
функция.
Объедините две идентичные копии изображения datastore imds
. Когда данные считываются из объединенного datastore, данные изображения возвращаются в двухколоночный массив ячеек, где первый столбец представляет изображения сетевого входа, а второй столбец содержит сетевые отклики.
dsCombined = combine(imds,imds); montage(preview(dsCombined)','Size',[6 2]) title("Combined Input and Response Pairs Before Augmentation")
Дополните каждую пару обучающих изображений серией операций обработки изображений:
Измените размеры входа и изображения ответа к 32 на 32 пикселя.
Добавьте соль и перец шум только к входу изображению.
Создайте преобразование, которое имеет рандомизированные шкалы и вращение.
Примените то же преобразование к входу и отклика.
Эти операции определены в вспомогательной функции imageRegressionAugmentationPipeline
в конце этого примера. Примените увеличение данных к обучающим данным при помощи transform
функция.
dsTrain = transform(dsCombined,@imageRegressionAugmentationPipeline); montage(preview(dsTrain)','Size',[6 2]) title("Combined Input and Response Pairs After Augmentation")
Полный пример, который включает обучение и оценку сети регрессии изображение-изображение, см. в разделе «Подготовка Datastore для регрессии изображение-изображение».
The classificationAugmentationPipeline
функция helper увеличивает изображения для классификации. dataIn
и dataOut
являются двухэлементными массивами ячеек, где первый элемент является входным изображением сети, а второй элемент - категориальной меткой.
function [dataOut,info] = classificationAugmentationPipeline(dataIn,info) dataOut = cell([size(dataIn,1),2]); for idx = 1:size(dataIn,1) temp = dataIn{idx}; % Add randomized Gaussian blur temp = imgaussfilt(temp,1.5*rand); % Add salt and pepper noise temp = imnoise(temp,'salt & pepper'); % Add randomized rotation and scale tform = randomAffine2d('Scale',[0.95,1.05],'Rotation',[-30 30]); outputView = affineOutputView(size(temp),tform); temp = imwarp(temp,tform,'OutputView',outputView); % Form second column expected by trainNetwork which is the expected response, % the categorical label in this case dataOut(idx,:) = {temp,info.Label(idx)}; end end
The imageRegressionAugmentationPipeline
Функция helper увеличивает изображения для регрессии изображение-изображение. dataIn
и dataOut
являются двухэлементными массивами ячеек, где первый элемент является входным изображением сети, а второй элемент - изображением сетевой характеристики.
function dataOut = imageRegressionAugmentationPipeline(dataIn) dataOut = cell([size(dataIn,1),2]); for idx = 1:size(dataIn,1) % Resize images to 32-by-32 pixels and convert to data type single inputImage = im2single(imresize(dataIn{idx,1},[32 32])); targetImage = im2single(imresize(dataIn{idx,2},[32 32])); % Add salt and pepper noise inputImage = imnoise(inputImage,'salt & pepper'); % Add randomized rotation and scale tform = randomAffine2d('Scale',[0.9,1.1],'Rotation',[-30 30]); outputView = affineOutputView(size(inputImage),tform); % Use imwarp with the same tform and outputView to augment both images % the same way inputImage = imwarp(inputImage,tform,'OutputView',outputView); targetImage = imwarp(targetImage,tform,'OutputView',outputView); dataOut(idx,:) = {inputImage,targetImage}; end end