В этом примере показано, как сегментировать и классифицировать рельеф местности в воздушных данных лидара как землю, здание и растительность. В примере в качестве входных данных используется файл LAZ, захваченный бортовой системой lidar. Сначала следует классифицировать данные облака точек в файле LAZ по точкам земли и без точек земли. Затем далее классифицируют негерметичные точки по объектам застройки и растительности на основе нормалей и особенностей кривизны. На этом рисунке представлен обзор процесса.

Загрузите данные облака точек и соответствующие метки истинности грунта из файла LAZ, aerialLidarData.laz, полученные из набора данных открытой топографии [1]. Точечное облако состоит из различных классов, включая наземный, строительный и растительный. Загрузите данные облака точек и соответствующие метки истинности грунта в рабочее пространство с помощью readPointCloud объектная функция lasFileReader объект. Визуализация облака точек с цветовым кодированием в соответствии с метками истинности земли с помощью pcshow функция.
lazfile = fullfile(toolboxdir('lidar'),'lidardata','las','aerialLidarData.laz'); % Read LAZ data from file lazReader = lasFileReader(lazfile); % Read point cloud and corresponding ground truth labels [ptCloud,pointAttributes] = readPointCloud(lazReader, ... 'Attributes','Classification'); grdTruthLabels = pointAttributes.Classification; % Visualize the input point cloud with corresponding ground truth labels figure pcshow(ptCloud.Location,grdTruthLabels) title('Aerial Lidar Data with Ground Truth')

Классификация грунта - это этап предварительной обработки для сегментации облака входных точек как наземного и не наземного. Сегментировать данные, загруженные из файла LAZ, в наземные и неназначенные точки с помощью segmentGroundSMRF функция.
[groundPtsIdx,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(ptCloud); % Visualize ground and non-ground points in green and magenta, respectively figure pcshowpair(nonGroundPtCloud,groundPtCloud) title('Classified Ground and Non-Ground Points')

Извлеките элементы из облака точек с помощью команды helperExtractFeatures функция. Все вспомогательные функции присоединены к этому примеру как вспомогательные файлы. Вспомогательная функция оценивает значения нормали и кривизны для каждой точки в облаке точек. Эти особенности обеспечивают базовую информацию о структуре в каждой точке, коррелируя ее с точками в ее окрестности.
Можно указать количество соседних узлов. Если число соседей слишком мало, вспомогательная функция переполняет точки вегетации. Если число соседей слишком велико, нет определяющей границы между зданиями и растительностью, так как точки растительности вблизи точек застройки неправильно классифицируются.
neighbors = 10;
[normals,curvatures,neighInds] = helperExtractFeatures(nonGroundPtCloud, ...
neighbors);Вспомогательная функция использует изменение нормалей и кривизны для различения зданий и растительности. Здания более планарны по сравнению с растительностью, поэтому изменение кривизны и относительная разница нормалей между соседями меньше для точек, принадлежащих постройкам. Точки растительности более разбросаны, что приводит к более значительному изменению кривизны по сравнению со зданиями. helperClassify функция классифицирует негерметичные точки по зданиям и растительности. Вспомогательная функция классифицирует точки как построенные на основе следующих критериев:
Кривизна каждой точки должна быть небольшой в пределах заданного порога кривизны, curveThresh.
Соседние точки должны иметь аналогичные нормали. Косинусное сходство между соседними нормалями должно быть больше заданного нормального порога, normalThresh.
Точки, не удовлетворяющие вышеуказанным критериям, отмечены как растительность. Вспомогательная функция помечает точки, принадлежащие растительности, как 1 и строительство в качестве 2.
% Specify the normal threshold and curvature threshold normalThresh = 0.85; curveThresh = 0.02; % Classify the points into building and vegetation labels = helperClassify(normals,curvatures,neighInds, ... normalThresh,curveThresh);
Извлеките метки класса здания и растительности из данных метки истинности земли. Поскольку в файле LAZ много классов, необходимо сначала изолировать классы грунта, зданий и растительности. Метки классификации соответствуют стандарту ASPRS для форматов файлов LAZ.
Классификационное значение 2 - Представляет точки основания
Классификационные значения 3, 4 и 5 - представляют низкие, средние и высокие точки растительности
Классификационное значение 6 - Представляет точки здания
Определить maskData извлекать точки, принадлежащие земле, зданиям и растительности, из облака входных точек.
maskData = grdTruthLabels>=2 & grdTruthLabels<=6;
Измените метки истинности грунта облака входных точек, указанные как grdTruthLabels.
% Compress low, medium, and high vegetation to a single value grdTruthLabels(grdTruthLabels>=3 & grdTruthLabels<=5) = 4; % Update grdTruthLabels for metrics calculation grdTruthLabels(grdTruthLabels == 2) = 1; grdTruthLabels(grdTruthLabels == 4) = 2; grdTruthLabels(grdTruthLabels == 6) = 3;
Сохранить прогнозируемые метки, полученные из предыдущих шагов классификации, в estimatedLabels.
estimatedLabels = zeros(ptCloud.Count,1); estimatedLabels(groundPtsIdx) = 1; estimatedLabels(labels == 1) = 2; estimatedLabels(labels == 2) = 3;
Извлеките метки, принадлежащие земле, зданиям и растительности.
grdTruthLabels = grdTruthLabels(maskData); estimatedLabels = estimatedLabels(maskData);
Визуализируйте местность с помощью наземной правды и оценочных меток.
ptCloud = select(ptCloud,maskData); hFig = figure('Position',[0 0 900 400]); axMap1 = subplot(1,2,1,'Color','black','Parent',hFig); axMap1.Position = [0 0.2 0.5 0.55]; pcshow(ptCloud.Location,grdTruthLabels,'Parent',axMap1) axis off title(axMap1,'Aerial Lidar Data with Ground Truth Labels') axMap2 = subplot(1,2,2,'Color','black','Parent',hFig); axMap2.Position = [0.5,0.2,0.5,0.55]; pcshow(ptCloud.Location,estimatedLabels,'Parent',axMap2) axis off title(axMap2,'Aerial Lidar Data with Classified Labels')

Проверка классификации путем вычисления суммарной точности в данном облаке точек наряду с точностью класса, пересечением (IoU) и взвешенным IoU.
confusionMatrix = segmentationConfusionMatrix(estimatedLabels,double(grdTruthLabels));
ssm = evaluateSemanticSegmentation({confusionMatrix}, ...
{'Ground' 'Vegetation' 'Building'},'Verbose',0);
disp(ssm.DataSetMetrics) GlobalAccuracy MeanAccuracy MeanIoU WeightedIoU
______________ ____________ _______ ___________
0.99762 0.99417 0.98168 0.99533
disp(ssm.ClassMetrics)
Accuracy IoU
________ _______
Ground 0.99996 0.99996
Vegetation 0.99195 0.9898
Building 0.99059 0.95526
readPointCloud | segmentGroundSMRF| pcnormals | pcshow | pcshowpair | segmentationConfusionMatrix | evaluateSemanticSegmentation
[1] Старр, Скотт. «Tuscaloosa, AL: сезонная динамика инундации и сообщества беспозвоночных». Национальный центр воздушного лазерного картирования, 1 декабря 2011 года. OpenTopography (https://doi.org/10.5069/G9SF2T3K)