В этом примере показано, как выполнять типичные методы увеличения объема данных, используемые в 3-D рабочих процессах обнаружения объектов с данными lidar.
Методы обнаружения объектов Lidar непосредственно предсказывают 3-D ограничивающие рамки вокруг интересующих объектов. Методы увеличения объема данных помогают повысить точность прогнозирования и избежать проблем с переоборудованием во время обучения. Этот пример охватывает методы глобального и локального увеличения: методы глобального увеличения применяются ко всему облаку точек сцены, а методы локального увеличения применяются только к точкам, принадлежащим отдельным объектам сцены.
Извлеките файл ZIP, присоединенный к этому примеру, во временную папку.
unzip('sampleWPIPointClouds.zip',tempdir); dataLocation = fullfile(tempdir,'sampleWPIPointClouds');
Создание хранилища данных для загрузки файлов PCD с помощью pcread функция.
lds = fileDatastore(dataLocation,'ReadFcn',@(x) pcread(x));Создайте хранилище данных меток рамки для загрузки 3-D ограничителей истинности основания.
load('sampleWPILabels.mat','trainLabels') bds = boxLabelDatastore(trainLabels);
Используйте combine позволяет объединить облака точек и 3-D ограничивающие рамки в одном хранилище данных.
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] степени.
Задайте случайное начальное число для воспроизводимости.
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 с помощью вспомогательной функции 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] Хахнер, Мартин, Денгсин Дай, Александр Линигер и Люк Ван Гул. «Количественное увеличение данных для обнаружения объектов 3D на основе LiDAR». Препринт, представлен 3 апреля 2020 года. https://arxiv.org/abs/2004.01643.