Увеличьте ограничительные рамки для обнаружения объектов

В этом примере показано, как использовать 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

Смотрите также

| | | | | |

Связанные примеры

Больше о