В этом примере показано, как сегментировать и классифицировать рельеф местности по данным воздушного лидара как землю, создание и растительность. В качестве входных данных в примере используется файл LAZ, захваченный воздушной системой лидара. Во-первых, классифицируйте данные облака точек в файле 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
функция. Все вспомогательные функции присоединены к этому примеру как вспомогательные файлы. Функция helper оценивает значения нормали и кривизны для каждой точки в облаке точек. Эти функции обеспечивают базовую информацию о структуре в каждой точке путем корреляции ее с точками в его окрестности.
Можно задать количество соседей, которые нужно учитывать. Если количество соседей слишком мало, вспомогательная функция разгоняет точки растительности. Если число соседей слишком велико, нет определяющего контура между созданиями и растительностью, так как точки растительности около точек создания неправильно классифицируются.
neighbors = 10;
[normals,curvatures,neighInds] = helperExtractFeatures(nonGroundPtCloud, ...
neighbors);
Функция-помощник использует изменение нормалей и кривизны, чтобы различать создания и растительность. Создания более планарны по сравнению с растительностью, поэтому изменение кривизны и относительное различие нормалей между соседями меньше для точек, принадлежащих созданиям. Точки растительности более рассеяны, что приводит к более высокому изменению кривизны по сравнению со созданиями. The helperClassify
функция классифицирует неземные точки в создание и растительность. Функция helper классифицирует точки как создания на основе следующих критериев:
Кривизна каждой точки должна быть маленькой, в пределах заданного порога кривизны curveThresh
.
Соседние точки должны иметь одинаковые нормали. Косинусоидальное сходство между соседними нормалями должно быть больше заданного нормального порога normalThresh
.
Точки, которые не удовлетворяют вышеуказанным критериям, отмечены как растительность. Функция helper помечает точки, принадлежащие растительности, следующим 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: Seasonal Inundation Dynamics and Fertebrate Communities (неопр.) (недоступная ссылка). Национальный центр воздушного лазерного отображения, 1 декабря 2011 года. OpenTopography (https://doi.org/10.5069/G9SF2T3K)