В этом примере показано, как выполнить типичные методы увеличения данных, используемые в 3-D рабочих процессах обнаружения объектов с данными о лидаре.
Лоцируйте методы обнаружения объектов, непосредственно предсказывают 3-D ограничительные рамки вокруг предметов интереса. Методы увеличения данных могут помочь вам улучшить точность предсказания и постараться не сверхсоответствовать проблемам в то время как обучение. Этот пример покрывает глобальные и локальные методы увеличения: глобальные методы увеличения применяются к облаку всего смысла сцены, и локальные методы увеличения применяются только к точкам, принадлежащим отдельным объектам в сцене.
Извлеките zip-файл, присоединенный к этому примеру к временной директории.
unzip('sampleWPIPointClouds.zip',tempdir); dataLocation = fullfile(tempdir,'sampleWPIPointClouds');
Создайте datastore файла, чтобы загрузить файлы PCD с помощью pcread
функция.
lds = fileDatastore(dataLocation,'ReadFcn',@(x) pcread(x));
Создайте 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 ограничительным рамкам с помощью функции помощника 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);
Выделяйте точки основной истины от исходного облака точек с помощью помощника funtion 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, Мартин, Денгксин Дэй, Александр Линиджер и Люк Ван Гул. "Определяя количество Увеличения Данных для LiDAR Основанное 3D Обнаружение объектов". Предварительно распечатайте, представленный 3 апреля 2020. https://arxiv.org/abs/2004.01643.