Main Content


Extract eigenvalue-based features from point cloud segments



features = extractEigenFeatures(ptCloud,labels) extracts eigenvalue-based features from a point cloud using labels, labels, that correspond to the segmented point cloud.

Eigenvalue-based features characterize geometrical features of point cloud segments. These features can be used in simultaneous localization and mapping (SLAM) applications for loop closure detection and localization in a target map.

features = extractEigenFeatures(segmentsIn) returns eigenvalue-based features from the point cloud segments segmentsIn. Use this syntax to facilitate the selection of specific segments in a point cloud scan for local feature extraction.

[features,segmentsOut] = extractEigenFeatures(___) additionally returns the segments extracted from the input point cloud using any combination of arguments from previous syntaxes. Use this syntax to facilitate visualization of the segments.

[___] = extractEigenFeatures(___,NormalizeEigenvalues=tf) normalizes the eigenvalues prior to computing features, specified as true or false. Set tf to true when the next step is to use a classifier to assign a semantic label to a 3-D point. Set tf to false when the next step is to find matching features. The default value is false.


collapse all

Load an organized lidar point cloud.

ld = load('drivingLidarPoints.mat');
ptCloud = ld.ptCloud; 

Segment and remove the ground plane.

groundPtsIdx = segmentGroundFromLidarData(ptCloud,'ElevationAngleDelta',15);
ptCloud = select(ptCloud,~groundPtsIdx,'OutputSize','full');

Cluster the remaining points with a minimum of 50 points per cluster.

distThreshold = 0.5; % in meters
minPoints = 50;
[labels,numClusters] = segmentLidarData(ptCloud,distThreshold,'NumClusterPoints',minPoints);

Compute eigenvalue-based features.

features = extractEigenFeatures(ptCloud,labels,'NormalizeEigenvalues',true)
features=17×1 object
  16x1 eigenFeature array with properties:


Create a Velodyne PCAP file reader.

veloReader = velodyneFileReader('lidarData_ConstructionRoad.pcap','HDL32E');

Read the first and fourth scans from the file.

ptCloud1 = readFrame(veloReader,1);
ptCloud2 = readFrame(veloReader,4);

Remove the ground plane from the scans.

maxDistance = 1; % in meters
referenceVector = [0 0 1];
[~,~,selectIdx] = pcfitplane(ptCloud1,maxDistance,referenceVector);
ptCloud1 = select(ptCloud1,selectIdx,'OutputSize','full');
[~,~,selectIdx] = pcfitplane(ptCloud2,maxDistance,referenceVector);
ptCloud2 = select(ptCloud2,selectIdx,'OutputSize','full');

Cluster the point clouds with a minimum of 10 points per cluster.

minDistance = 2; % in meters
minPoints = 10;
labels1 = pcsegdist(ptCloud1,minDistance,'NumClusterPoints',minPoints);
labels2 = pcsegdist(ptCloud2,minDistance,'NumClusterPoints',minPoints);

Extract eigen-value features and the corresponding segments from each point cloud.

[eigFeatures1,segments1] = extractEigenFeatures(ptCloud1,labels1);
[eigFeatures2,segments2] = extractEigenFeatures(ptCloud2,labels2);

Create matrices of the features and centroids extracted from each point cloud, for matching.

features1 = vertcat(eigFeatures1.Feature);
features2 = vertcat(eigFeatures2.Feature);
centroids1 = vertcat(eigFeatures1.Centroid);
centroids2 = vertcat(eigFeatures2.Centroid);

Find putative feature matches.

indexPairs = pcmatchfeatures(features1,features2, ...

Get the matched segments and features for visualization.

matchedSegments1 = segments1(indexPairs(:,1));
matchedSegments2 = segments2(indexPairs(:,2));
matchedFeatures1 = eigFeatures1(indexPairs(:,1));
matchedFeatures2 = eigFeatures2(indexPairs(:,2));

Visualize the matches.

title('Matched Segments')

Figure contains an axes object. The axes object with title Matched Segments contains 5 objects of type scatter, line.

Input Arguments

collapse all

Point cloud, specified as a pointCloud object.

Cluster labels, specified as an M-element vector of numeric values for unorganized point clouds or an M-by-N matrix of numeric values for organized point clouds. The labels correspond to the results of segmenting the input point cloud. Each point in the point cloud has a cluster label, specified by the corresponding element in labels.

You can use the pcsegdist or the segmentLidarData function to return labels.

Point cloud segments, specified as a vector of pointCloud objects. Each point cloud segment in the input must have a minimum of two points for feature extraction. No features or segments are returned for input segments with only one point.

Output Arguments

collapse all

Eigenvalue-based features, returned as a vector of eigenFeature objects. When you extract features from a labeled point cloud input, each element in this vector contains the features extracted from the corresponding cluster of labeled points. When you extract features from a segments input, each element in this vector contains the features extracted from the corresponding element in the segments vector.

Segments extracted from the point cloud, specified as a vector of pointCloud objects. The length of the segments vector corresponds to the number of nonzero, unique labels.


[1] Weinmann, M., B. Jutzi, and C. Mallet. “Semantic 3D Scene Interpretation: A Framework Combining Optimal Neighborhood Size Selection with Relevant Features.” ISPRS Annals of Photogrammetry, Remote Sensing and Spatial Information Sciences II–3 (August 7, 2014): 181–88.

Introduced in R2021a