В этом примере показано, как выполнить типичные методы увеличения данных, используемые в 3-D рабочих процессах обнаружения объектов с помощью лидарных данных.
Методы обнаружения объектов лидар непосредственно предсказывают 3-D ограничительные рамки вокруг интересующих объектов. Методы увеличения данных могут помочь вам улучшить точность предсказания и избежать избыточной подгонки проблем во время обучения. Этот пример охватывает глобальные и локальные методы увеличения: методы глобального увеличения применяются ко всему облаку точек сцены, а локальные методы увеличения применяются только к точкам, принадлежащим отдельным объектам сцены.
Извлечение ZIP- файла, присоединенного к этому примеру, к временной директории.
unzip('sampleWPIPointClouds.zip',tempdir); dataLocation = fullfile(tempdir,'sampleWPIPointClouds');
Создайте файл datastore, чтобы загрузить файлы PCD с помощью pcread
функция.
lds = fileDatastore(dataLocation,'ReadFcn',@(x) pcread(x));
Создайте box label datastore для загрузки 3-D основных истин ограничивающих рамок.
load('sampleWPILabels.mat','trainLabels') bds = boxLabelDatastore(trainLabels);
Используйте combine
функция для объединения облаков точек и 3-D ограничивающих рамок в одном datastore.
cds = combine(lds,bds);
Отобразите облако точек.
inputData = read(cds); ptCloud = inputData{1,1}; gtLabels = inputData{1,2}; figure; ax = pcshow(ptCloud.Location);
Нарисуйте 3-D ограничительные рамки над облаком точек.
showShape('cuboid',gtLabels,'Parent',ax,'Opacity',0.1, ... 'Color','green','LineWidth',0.5); zoom(ax,2);
reset(cds);
Глобальные данные используются, когда облака точек в наборе данных имеют небольшие изменения. Глобальный метод применяет преобразование ко всему облаку точек, чтобы сгенерировать новые выборки облака точек, которые не присутствуют в исходном наборе данных. То же преобразование применяется ко всем соответствующим основным блокам истинности. Следующие четыре глобальных метода увеличения количества данных обычно используются [1].
Случайное вращение
Случайное масштабирование
Случайный перевод
Случайное отражение
Случайным образом поверните облако точек и 3-D ограничивающие рамки в заданной области углов вдоль оси Z. Случайным образом повернув облако точек, можно симулировать точки данных, такие как транспортное средство, совершающая поворот. Типичная область значений для вращения [-45 45]
степени.
Установите случайный seed для повторяемости.
rng(1);
Задайте минимальный и максимальный углы рыскания для вращения.
minYawAngle = -45; maxYawAngle = 45;
Определите размер сетки, в которую будет помещено облако точек.
gridSize = [32 32 32];
Определите пределы необходимой области в облаке точек.
axisLimits = [-100 100];
Создайте выход вид для аффинного преобразования.
outView = imref3d(gridSize,axisLimits,axisLimits,axisLimits);
Вычислите случайный угол из заданной области значений углов рыскания.
theta = minYawAngle + rand*(maxYawAngle - minYawAngle)
theta = -7.4680
Создайте преобразование, которое поворачивает облака точек и 3-D ограничивающие рамки.
tform = randomAffine3d('Rotation',@() deal([0,0,1],theta));
Примените преобразование к облаку точек.
ptCloudTransformed = pctransform(ptCloud,tform);
Примените то же преобразование к 3-D ограничивающим рамкам.
gtLabelsTranformed = bboxwarp(gtLabels,tform,outView);
Отображение повернутого облака точек и основных блоков истинности.
figure; ax1 = pcshow(ptCloudTransformed.Location); showShape('cuboid',gtLabelsTranformed,'Parent',ax1,'Opacity',0.1, ... 'Color','green','LineWidth',0.5); zoom(ax1,2);
Случайным образом масштабируйте облако точек и 3-D ограничивающие рамки из заданной области шкал. Типичная область значений масштабирования [0.95 1.05]
. В примере используется область значений [0.5 0.7]
для улучшения визуализации.
Создайте преобразование, чтобы масштабировать облако точек и 3-D ограничивающие рамки.
tform = randomAffine3d('Scale',[0.5 0.7]);
Примените преобразование к облаку точек.
ptCloudTransformed = pctransform(ptCloud,tform);
Примените то же преобразование к 3-D ограничивающим рамкам.
gtLabelsTranformed = bboxwarp(gtLabels,tform,outView);
Отображение масштабированного облака точек и основных блоков истинности.
figure; ax2 = pcshow(ptCloudTransformed.Location); showShape('cuboid',gtLabelsTranformed,'Parent',ax2,'Opacity',0.1, ... 'Color','green','LineWidth',0.5); zoom(ax2,2);
Случайным образом переместите облако точек и 3-D ограничивающие рамки вдоль осей x -, y - и z - из заданной области.
Создайте преобразование, чтобы переместить облако точек и 3-D ограничительные рамки.
tform = randomAffine3d('XTranslation',[0 0.2],... 'YTranslation',[0 0.2],... 'ZTranslation',[0 0.1]);
Примените преобразование к облаку точек.
ptCloudTransformed = pctransform(ptCloud,tform);
Примените то же преобразование к 3-D ограничивающим рамкам.
gtLabelsTranformed = bboxwarp(gtLabels,tform,outView);
Отображение переведенного облака точек и основных блоков истинности.
figure; ax3 = pcshow(ptCloudTransformed.Location); showShape('cuboid',gtLabelsTranformed,'Parent',ax3,'Opacity',0.1,'Color', ... 'green','LineWidth',0.5); zoom(ax3,2);
Случайным образом разверните облако точек и 3-D ограничивающие рамки вдоль оси Y. Не поворачивайте вдоль оси X, так как аннотации ограничивающего прямоугольника предусмотрены в поле зрения камеры.
Создайте преобразование, чтобы развернуть облако точек и 3-D ограничивающие рамки.
tform = randomAffine3d('YReflection',true);
Примените преобразование к облаку точек.
ptCloudTransformed = pctransform(ptCloud,tform);
Примените то же преобразование к ограничивающим 3-D прямоугольникам с помощью функции helper flipBbox
, присоединенный к этому примеру как вспомогательный файл.
gtLabels = flipBbox(gtLabels,tform);
Отобразите развернутое облако точек и основные блоки истинности.
figure; ax4 = pcshow(ptCloudTransformed.Location); showShape('cuboid',gtLabels,'Parent',ax4,'Opacity',0.1, ... 'Color','green','LineWidth',0.5); zoom(ax4,2);
Достоверные данные увеличение - это метод, при котором во время обучения в текущее облако обучающих точек [1] вводятся случайным образом выбранные основные блоки истинности из других облаков точек. Используя этот подход, можно увеличить количество основных блоков истинности для облака точек и моделировать объекты, существующие в различных окружениях. Чтобы избежать физически невозможных результатов, вы выполняете тест столкновения для добавляемых выборок и основных блоков истинности текущего облака точек. Используйте этот метод увеличения, когда существует дисбаланс классов в наборе данных.
Используйте generateGTDataForAugmentation
и groundTruthDataAugmentation
вспомогательные функции, присоединенные к этому примеру как вспомогательные файлы, чтобы случайным образом добавить фиксированное количество объектов в облако точек из класса автомобиля.
trainData = lds.readall; gtData = generateGTDataForAugmentation(trainData,trainLabels);
Задайте количество основных блоков истинности.
numSamplesToAdd = 3; cdsAugmented = transform(cds,@(x) groundTruthDataAugmenation(x,gtData,numSamplesToAdd));
Отобразите облако точек вместе с рамками с увеличенной основной истиной.
augData = read(cdsAugmented); augptCld = augData{1,1}; augLabels = augData{1,2}; figure; ax5 = pcshow(augptCld(:,1:3)); showShape('cuboid',augLabels,'Parent',ax5,'Opacity',0.1, ... 'Color','green','LineWidth',0.5); zoom(ax5,2);
Увеличение локальных данных применяется только к точкам внутри основных блоков истинности, а не ко всему облаку точек [1]. Увеличение локальных данных может использоваться, когда вы хотите применить преобразования только к точкам в основных блоках истинности. Остальная часть облака точек остается прежней.
Прочтите облако точек и соответствующую метку основной истины.
inputData = read(cds);
ptCloud = inputData{1,1};
gtLabels = inputData{1,2};
gtLabelsTransformed = zeros(size(gtLabels));
for i = 1:size(gtLabels,1)
labelParams = gtLabels(i,:);
centroidLoc = labelParams(1,1:3);
model = cuboidModel(labelParams);
indices = findPointsInsideCuboid(model, ptCloud);
numPointsInside = size(indices,1);
Отделите точки основной истины от исходного облака точек с помощью вспомогательного removeIndicesFromPointCloud финансирования
, присоединенный к этому примеру как вспомогательный файл.
updatedPtCloud = removeIndicesFromPtCloud(ptCloud,indices); cubPtCloud = select(ptCloud,indices); % Shift the segregrated point cloud to the origin. numPoints = cubPtCloud.Count; shiftRange = -1.*repmat(centroidLoc,[numPoints 1]); cubPtCloud = pctransform(cubPtCloud,shiftRange); % Define the minimum and maximum yaw angles for rotation. minYawAngle = -45; maxYawAngle = 45; % Calculate a random angle from the specified yaw angle range. theta = minYawAngle + rand*(maxYawAngle - minYawAngle); % Create a transformation that rotates, translates, and scales the % point clouds and 3-D bounding boxes. tform = randomAffine3d('Rotation',@() deal([0,0,1],theta),... 'Scale',[0.95,1.05],... 'XTranslation',[0,0.2],... 'YTranslation',[0,0.2],... 'ZTranslation',[0,0.1]); % Apply the transfomation to the 3-D bounding box. labelParams(1,1:3) = labelParams(1,1:3) - centroidLoc; labelParamsTransformed = bboxwarp(labelParams,tform,outView); % Calculate the overlap ratio between the transformed box and the % original ground truth boxes by converting them to rotated rectangle % format, defined as [xcenter,ycenter,width,height,yaw]. overlapRatio = bboxOverlapRatio(labelParamsTransformed(:,[1,2,4,5,9]), ... gtLabels(:,[1,2,4,5,9])); [maxOverlapRatio, maxOverlapIdx] = max(overlapRatio); % Check to see if any transformed boxes overlap with the ground truth % boxes. if (maxOverlapRatio > 0) && (maxOverlapIdx ~= i) shiftRange = -1.*shiftRange; cubPtCloud = pctransform(cubPtCloud,shiftRange); updatedPtCloud = pccat([updatedPtCloud,cubPtCloud]); gtLabelsTransformed(i,1) = labelParams; else cubPtCloudTransformed = pctransform(cubPtCloud,tform); shiftRange = -1.*shiftRange; cubPtCloudTransformed = pctransform(cubPtCloudTransformed,shiftRange); updatedPtCloud = pccat([updatedPtCloud,cubPtCloudTransformed]); gtLabelsTransformed(i,:) = labelParamsTransformed; end gtLabelsTransformed(i,1:3) = gtLabelsTransformed(i,1:3) + centroidLoc; ptCloud = updatedPtCloud; end
Отобразите облако точек вместе с дополненными основными блоками истинности.
figure; ax6 = pcshow(updatedPtCloud.Location); showShape('cuboid',gtLabelsTransformed,'Parent',ax6,'Opacity',0.1, ... 'Color','green','LineWidth',0.5); zoom(ax6,2);
reset(cds);
[1] Hahner, Martin, Dengxin Dai, Alexander Liniger, and Luc Van Gool. «Количественная оценка увеличения количества данных для ЛИДАРА на основе 3D Обнаружения объектов». Препринт, представленный 3 апреля 2020 года. https://arxiv.org/abs/2004.01643.