Main Content

detectLoop

Detect loop closures

Description

example

loopViewIds = detectLoop(loopDetector) detects loop closures for the last added descriptor and returns the view identifiers loopViewIds that correspond to loop closures. If the function detects no loop closures, loopViewIds is empty. The loop closure detector ignores the number of most recently added descriptors, set by the NumExcludedDescriptors name-value argument, to avoid detecting loop closures against recent descriptors.

loopViewIds = detectLoop(loopDetector,descriptor) detects loop closures using the scan context descriptor descriptor.

[loopViewIds,dists] = detectLoop(___) returns the scan context distances dists between the loop descriptor and the query descriptors, using any combination of input arguments from previous syntaxes. The function computes distance between scan context descriptors, normalized to the range [0,1], using a modified cosine distance.

[___] = detectLoop(___,Name=Value) specifies options using one or more name-value arguments in addition to any combination of arguments from the previous syntaxes. For example, detectLoop(loopDetector,NumExcludedDescriptors=15) detects loop closures for the last added descriptor while ignoring only the 15 most recently added loop descriptors.

Examples

collapse all

Create a loop closure detector.

loopDetector = scanContextLoopDetector;

Create a Velodyne PCAP file reader.

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

Read the point clouds and extract the scan context descriptor from each point cloud scan. Add the descriptors to the detector.

for viewId = 1:10
    ptCloud = readFrame(veloReader,viewId);
    descriptor = scanContextDescriptor(ptCloud);
    addDescriptor(loopDetector,viewId,descriptor);
end

Check if the next point cloud can be classified as a loop closure detection without excluding any recently added descriptors.

viewId = viewId + 1;
ptCloud = readFrame(veloReader,viewId);
descriptor = scanContextDescriptor(ptCloud);
[loopViewId,dists] = detectLoop(loopDetector,descriptor,'NumExcludedDescriptors',0)
loopViewId = uint32
    10
dists = single
    0.0831

Input Arguments

collapse all

Loop closure detector, specified as a scanContextLoopDetector object.

Scan context descriptor, specified as an M-by-N matrix, where M is the number of radial bins and N is the number of azimuthal bins.

Name-Value Arguments

Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

Example: detectLoop(loopDetector,NumExcludedDescriptors=15) detects loop closures for the last added descriptor while ignoring only the 15 most recently added loop descriptors.

Scan distance threshold to classify a view as a loop closure, specified as a positive scalar. Increasing this value can return more loop closures, but this can also increase false positives.

Number of most recently added descriptors to exclude as loop closure candidates, specified as a nonnegative integer. Exclude the most recently added descriptors to avoid detecting loop closures for the most recently added descriptor against recent descriptors. Increase NumExcludedDescriptors if many consecutive descriptors correspond to the same area.

Search radius in a subdescriptor space, specified as a positive scalar. The function computes the scan context distance for only those descriptors within the search radius. Increasing this value can return more loop closures, but can also increase false positives. Typical values range between 0.2 and 0.4.

Maximum number of strongest loop closure detections returned, specified as a positive integer. Increase this value to increase the potential number of loop closure detections returned. However, increasing this value can decrease computation speed. Set this value to Inf to return all loop closure detections.

Output Arguments

collapse all

Loop closure view identifiers corresponding to loop closures, returned as a P-element vector of integer values. If the function finds no loop closures, it returns loopViewIds as an empty vector. The loop closure detector ignores the last NumExcludedDescriptors descriptors to avoid detecting loop closures against recent descriptors.

Scan context distances, returned as a P-element vector of positive values. The distances represent the scan context distance between the loop descriptor and the corresponding query descriptor. The function computes the distance between scan context descriptors, normalized to the range [0,1], using a modified cosine distance.

Algorithms

The ring key descriptor is a subdescriptor extracted from a scan context descriptor. It is the occupancy ratio of each azimuthal bin that makes it rotation-invariant.

The scan context loop closure detector is a two-phase algorithm. It first uses the ring key descriptor for a nearest neighbor search to find candidate loop closures. Then, it computes the scan context distance using the scan context descriptors, and thresholds it to identify the best loop closure detections.

Introduced in R2021b