В этом примере показано, как использовать MATLAB®, Computer Vision Toolbox™ и Image Processing Toolbox™, чтобы выполнить общие виды поля изображения и увеличения ограничительной рамки как часть рабочих процессов обнаружения объектов.
Обучающие данные детектора объектов состоят из изображений и сопоставленных меток ограничительной рамки. Когда вы увеличиваете обучающие данные, необходимо применить идентичные преобразования к изображению и сопоставленным ограничительным рамкам. Этот пример демонстрирует три общих типа преобразований:
Пример затем показывает, как применить увеличение к обучающим данным в хранилищах данных с помощью комбинации нескольких типов преобразований.
Можно использовать увеличенные обучающие данные, чтобы обучить сеть. Для примера, показывающего, как обучить сеть обнаружения объектов, смотрите, что Обнаружение объектов Использует Глубокое обучение Faster R-CNN (Computer Vision Toolbox).
Считайте и отобразите демонстрационное поле изображения и ограничительную рамку. Чтобы сравнить эффекты различных типов увеличения, каждое преобразование в этом примере использует то же входное поле изображения и ограничительную рамку.
filenameImage = 'kobi.png'; I = imread(filenameImage); bbox = [4 156 1212 830]; label = "dog";
Отобразите поле изображения и ограничительную рамку.
annotatedImage = insertShape(I,"rectangle",bbox,"LineWidth",8); imshow(annotatedImage) title('Original Image and Bounding Box')
Используйте imresize
уменьшать масштаб изображения фактором 2.
scale = 1/2; J = imresize(I,scale);
Используйте bboxresize
применять то же масштабирование к связанной ограничительной рамке.
bboxResized = bboxresize(bbox,scale);
Отобразите измененное поле изображения и ограничительную рамку.
annotatedImage = insertShape(J,"rectangle",bboxResized,"LineWidth",8); imshow(annotatedImage) title('Resized Image and Bounding Box')
Обрезка является общим шагом предварительной обработки, чтобы заставить данные совпадать с входным размером сети. Чтобы создать выходные изображения желаемого размера, сначала задайте размер и положение окна обрезки при помощи randomCropWindow2d
и centerCropWindow2d
функции. Убедитесь, что вы выбираете окно обрезки, которое включает желаемое содержимое в изображение. Затем обрежьте изображение и пиксельное изображение метки к тому же окну при помощи imcrop
.
Задайте желаемый размер обрезанной области как двухэлементный вектор формы [высота, ширина].
targetSize = [1024 1024];
Обрежьте изображение к целевому размеру от центра изображения при помощи imcrop
.
win = centerCropWindow2d(size(I),targetSize); J = imcrop(I,win);
Обрежьте ограничительные рамки с помощью того же окна обрезки при помощи bboxcrop
. Задайте OverlapThreshold
как значение меньше чем 1 так, чтобы функция отсекла ограничительные рамки к окну обрезки вместо того, чтобы отбросить их, когда окно обрезки не полностью заключает ограничительную рамку. Порог перекрытия позволяет вам управлять объемом усечения, которое терпимо для объектов в ваших изображениях. Например, усечение больше чем половины человека не полезно для обучения детектор человека, тогда как усечение половины транспортного средства может быть терпимым.
[bboxCropped,valid] = bboxcrop(bbox,win,"OverlapThreshold",0.7);
Сохраните метки, которые являются в окне обрезки.
label = label(valid);
Отобразите кадрированное изображение и ограничительную рамку.
annotatedImage = insertShape(J,"rectangle",bboxCropped,"LineWidth",8); imshow(annotatedImage) title('Cropped Image and Bounding Box')
Обрезка и изменение размеров часто выполняются вместе. Можно использовать bboxcrop
и bboxresize
последовательно реализовать обычно используемую "обрезку и изменить размер" преобразования.
Создайте окно обрезки из случайного положения в изображении. Обрежьте поле изображения и ограничительную рамку к тому же окну обрезки.
cropSize = [1024 1024];
win = randomCropWindow2d(size(I),cropSize);
J = imcrop(I,win);
croppedBox = bboxcrop(bbox,win,"OverlapThreshold",0.5);
Измените размер изображения и поля к целевому размеру.
targetSize = [512 512]; J = imresize(J,targetSize); croppedAndResizedBox = bboxresize(croppedBox,targetSize./cropSize);
Отобразите обрезанное и измененное поле изображения и ограничительную рамку.
annotatedImage = insertShape(J,"rectangle",croppedAndResizedBox,"LineWidth",8); imshow(annotatedImage) title('Crop and Resized Image and Bounding Box')
randomAffine2d
функция создает рандомизированное 2D аффинное преобразование из комбинации вращения, перевода, масштабируясь (изменение размеров), отражение и сдвиг. Деформируйте изображение при помощи imwarp
. Деформируйте ограничительные рамки при помощи bboxwarp
. Управляйте пространственными границами и разрешением деформированного выхода при помощи affineOutputView
функция.
Этот пример демонстрирует два из рандомизированных аффинных преобразований: масштабирование и вращение.
Создайте преобразование шкалы, которое изменяет размер входного поля изображения и ограничительной рамки с помощью масштабного коэффициента, выбранного случайным образом из области значений [1.5 1.8]. Это преобразование применяет тот же масштабный коэффициент в горизонтальных и вертикальных направлениях.
tform = randomAffine2d("Scale",[1.5 1.8]);
Создайте выходное представление для смежного преобразования.
rout = affineOutputView(size(I),tform);
Вращайте изображение с помощью imwarp
и вращайте ограничительную рамку с помощью bboxwarp
. Задайте OverlapThreshold
значение 0,5.
J = imwarp(I,tform,"OutputView",rout); bboxScaled = bboxwarp(bbox,tform,rout,"OverlapThreshold",0.5);
Отобразите масштабированное поле изображения и ограничительную рамку.
annotatedImage = insertShape(J,"rectangle",bboxScaled,"LineWidth",8); imshow(annotatedImage) title('Scaled Image and Bounding Box')
Создайте рандомизированное преобразование вращения, которое вращает изображение и метки поля углом, выбранным случайным образом из области значений [-15,15] степени.
tform = randomAffine2d("Rotation",[-15 15]);
Создайте выходное представление для imwarp
и bboxwarp
.
rout = affineOutputView(size(I),tform);
Вращайте изображение с помощью imwarp
и вращайте ограничительную рамку с помощью bboxwarp
. Задайте OverlapThreshold
значение 0,5.
J = imwarp(I,tform,"OutputView",rout); bboxRotated = bboxwarp(bbox,tform,rout,"OverlapThreshold",0.5);
Отобразите кадрированное изображение и ограничительную рамку. Обратите внимание на то, что ограничительная рамка, возвращенная bboxwarp
всегда выравнивается к осям изображений. Размер и соотношение сторон ограничительной рамки изменяются, чтобы разместить вращаемый объект.
annotatedImage = insertShape(J,"rectangle",bboxRotated,"LineWidth",8); imshow(annotatedImage) title('Rotated Image and Bounding Box')
Хранилища данных являются удобным способом считать и увеличить наборы данных. Создайте datastore, который хранит поле изображения и данные об ограничительной рамке, и увеличьте данные с помощью ряда нескольких операций.
Чтобы увеличить размер демонстрационных хранилищ данных, реплицируйте имена файлов изображения и ограничительной рамки и меток.
numObservations = 4; images = repelem({filenameImage},numObservations,1); bboxes = repelem({bbox},numObservations,1); labels = repelem({label},numObservations,1);
Создайте imageDatastore
от учебных файлов изображений. Объедините ограничительную рамку и пометьте данные в таблице, затем создайте boxLabelDatastore
из таблицы.
imds = imageDatastore(images); tbl = table(bboxes,labels); blds = boxLabelDatastore(tbl);
Сопоставьте изображение и пары метки поля путем объединения datastore изображений и datastore метки поля.
trainingData = combine(imds,blds);
Считайте первое изображение и его assocated метку поля от объединенного datastore.
data = read(trainingData); I = data{1}; bboxes = data{2}; labels = data{3};
Отобразите изображение и данные о метке поля.
annotatedImage = insertObjectAnnotation(I,'rectangle',bbox,labels, ... 'LineWidth',8,'FontSize',40); imshow(annotatedImage)
Примените увеличение данных к обучающим данным при помощи transform
функция. Этот пример выполняет два отдельных увеличения к обучающим данным.
Первые дрожания увеличения цвет изображения и затем выполняют идентичное случайное горизонтальное отражение и вращение на изображении и парах метки поля. Эти операции заданы в jitterImageColorAndWarp
функция помощника в конце этого примера.
augmentedTrainingData = transform(trainingData,@jitterImageColorAndWarp);
Считайте все увеличенные данные.
data = readall(augmentedTrainingData);
Отобразите увеличенное изображение и данные о метке поля.
rgb = cell(numObservations,1); for k = 1:numObservations I = data{k,1}; bbox = data{k,2}; labels = data{k,3}; rgb{k} = insertObjectAnnotation(I,'rectangle',bbox,labels,'LineWidth',8,'FontSize',40); end montage(rgb)
Второе увеличение повторно масштабирует изображение и метку поля к целевому размеру. Эти операции заданы в resizeImageAndLabel
функция помощника в конце этого примера.
targetSize = [300 300];
preprocessedTrainingData = transform(augmentedTrainingData,...
@(data)resizeImageAndLabel(data,targetSize));
Считайте все предварительно обработанные данные.
data = readall(preprocessedTrainingData);
Отобразите предварительно обработанное изображение и данные о метке поля.
rgb = cell(numObservations,1); for k = 1:numObservations I = data{k,1}; bbox = data{k,2}; labels = data{k,3}; rgb{k} = insertObjectAnnotation(I,'rectangle',bbox,labels, ... 'LineWidth',8,'FontSize',15); end montage(rgb)
jitterImageColorAndWarp
функция помощника применяет дрожание произвольного цвета к данным изображения, затем применяет идентичное аффинное преобразование к изображению и данным о метке поля. Преобразование состоит из случайного горизонтального отражения и вращения. Вход data
и выход out
двухэлементные массивы ячеек, где первый элемент является данными изображения, и второй элемент является данными о метке поля.
function out = jitterImageColorAndWarp(data) % Unpack original data. I = data{1}; boxes = data{2}; labels = data{3}; % Apply random color jitter. I = jitterColorHSV(I,"Brightness",0.3,"Contrast",0.4,"Saturation",0.2); % Define random affine transform. tform = randomAffine2d("XReflection",true,'Rotation',[-30 30]); rout = affineOutputView(size(I),tform); % Transform image and bounding box labels. augmentedImage = imwarp(I,tform,"OutputView",rout); [augmentedBoxes, valid] = bboxwarp(boxes,tform,rout,'OverlapThreshold',0.4); augmentedLabels = labels(valid); % Return augmented data. out = {augmentedImage,augmentedBoxes,augmentedLabels}; end
resizeImageAndLabel
функция помощника вычисляет масштабный коэффициент для изображения, чтобы совпадать с целевым размером, затем изменяет размер изображения с помощью imresize
и метка поля с помощью bboxresize
. Входные и выходные данные являются двухэлементными массивами ячеек, где первый элемент является данными изображения, и второй элемент является данными о метке поля.
function data = resizeImageAndLabel(data,targetSize) scale = targetSize./size(data{1},[1 2]); data{1} = imresize(data{1},targetSize); data{2} = bboxresize(data{2},scale); end
bboxcrop
| bboxresize
| bboxwarp
| centerCropWindow2d
| imcrop
| imresize
| randomCropWindow2d