Create Class for Loading Custom Ground Truth Data Sources
In the Ground Truth Labeler app, you can label signals from image and point cloud data sources. These sources include videos, image sequences, point cloud sequences, Velodyne® packet capture (PCAP) files, and rosbags. To load data sources that the app does not natively support, you can create a class to load that source into the app.
This example shows how to use one of the predefined data source classes
that load signals from data sources into the Ground Truth Labeler app: the vision.labeler.loading.PointCloudSequenceSource class. The app uses this
specific class to load sequences of point cloud data (PCD) or polygon (PLY) files from a
folder.
To get started, open the vision.labeler.loading.PointCloudSequenceSource
class. Use the properties and methods described for this class to help you write your own
custom class.
edit vision.labeler.loading.PointCloudSequenceSourceCustom Class Folder
The Ground Truth Labeler app recognizes data source classes only if those
files are in a +vision/+labeler/+loading folder that is on the
MATLAB® search path.
The vision.labeler.loading.PointCloudSequenceSource class and other
predefined data source classes are stored in this folder.
matlabroot\toolbox\vision\vision\+vision\+labeler\+loading
In this path, is the root of
your MATLAB folder.matlabroot
Save the data source classes that you create to this folder. Alternatively, create
your own +vision/+labeler/+loading folder, add it to the MATLAB search path, and save your class to this folder.
Class Definition
Data source classes must inherit from the vision.labeler.loading.MultiSignalSource class. View the class definition
for the vision.labeler.loading.PointCloudSequenceSource class.
classdef PointCloudSequenceSource < vision.labeler.loading.MultiSignalSourceWhen you load a point cloud sequence signal into the Ground Truth Labeler
app, the app creates an instance of the class, that is, a
PointCloudSequenceSource object. After labeling this signal in
the app, when you export the labels, the exported groundTruthMultisignal object stores this
PointCloudSequenceSource object in its
DataSource property.
When defining your data source class, replace
PointCloudSequenceSource with the name of your custom data source
class.
Class Properties
Data source classes must define these abstract, constant properties.
Name— A string scalar specifying the type of the data sourceDescription— A string scalar describing the class
In the Ground Truth Labeler app, when you load signals from the Add/Remove
Signal dialog box, the Name string appears as an option in the
Source Type parameter. This figure shows the
Name string for the
vision.labeler.loading.PointCloudSequenceSource class.

The Description string does not appear in the
dialog box. However, both the Name and
Description strings are stored as read-only properties in
instances of this class.
This code shows the Name and Property
strings for the vision.labeler.loading.PointCloudSequenceSource
class.
properties (Constant) Name = "Point Cloud Sequence" Description = "A PointCloud sequence reader" end
When defining your data source class, define the Name and
Description property values to match the name and description
of your custom data source. You can also define any additional private properties that
are specific to loading your data source. The source-specific properties for the
vision.labeler.loading.PointCloudSequenceSource class are not shown
in this example, but you can view them in the class file.
Method to Customize Load Panel
In data source classes, the customizeLoadPanel method controls the
display of the panel for loading signals in the Add/Remove Signal dialog box of the app.
This panel is a Panel object created by using the uipanel function. The panel contains the parameters and controls needed
to load signals from data sources.
This figure shows the loading panel for the
vision.labeler.loading.PointCloudSequenceSource class. In the
Source Type list, when you select Point Cloud
Sequence, the app calls the customizeLoadPanel method
and loads the panel for point cloud sequences.

This code shows the customizeLoadPanel method for the
vision.labeler.loading.PointCloudSequenceSource class. It uses the
computePositions method to calculate the position values where
the UI components such as text, buttons and parameters must be placed. The
addUIComponents method then defines the panel by adding the UI
components accordingly. For complete implementation of these methods, refer to the code
for the vision.labeler.loading.PointCloudSequenceSource class.
function customizeLoadPanel(this, panel) this.Panel = panel; computePositions(this); addUIComponents(this); end
When developing this method or other data source methods, you can use the static
method loadPanelChecker to preview the display and functionality of
the loading dialog box for your custom data source. This method does not require you to
have an app session open to use it. For example, use the
loadPanelChecker method with the
vision.labeler.loading.PointCloudSequence class.
vision.labeler.loading.PointCloudSequenceSource.loadPanelChecker
Methods to Get Load Panel Data and Load Data Source
In the Add/Remove Signal dialog box, after you browse for a signal, set the necessary parameters, and click Add Source, the app calls these two methods in succession.
getLoadPanelData— Get the data entered into the panel.loadSource— Load the data into the app.
This figure shows the relationship between these methods and the Add
Source button when loading a point cloud sequence signal by using the
vision.labeler.loading.PointCloudSequenceSource class.

When defining a custom data source, you must define the
getLoadPanelData method, which returns these outputs.
sourceName— The name of the data sourcesourceParams— A structure containing fields with information required to load the data source
This code shows the getLoadPanelData method for the
vision.labeler.loading.PointCloudSequenceSource class. This method
sets sourceName to the name entered in the Folder
Name parameter of the dialog box and sourceParams
to an empty structure. If the Timestamps parameter is set to
From Workspace and has timestamps loaded, then the app
populates this structure with those timestamps.
function [sourceName, sourceParams] = getLoadPanelData(this) sourceParams = struct(); if isUIFigureBased(this) sourceName = string(this.FolderPathBox.Value); else sourceName = string(this.FolderPathBox.String); end end
You must also define the loadSource method in your custom data class.
This method must take the sourceName and
sourceParams returned from the
getLoadPanelData method as inputs. This method must also populate
these properties, which are stored in the instance of the data source object that the
app creates.
SignalName— String identifiers for each signal in a data sourceSignalType— An array ofvision.labeler.loading.SignalTypeenumerations defining the type of each signal in the data sourceTimestamp— A vector or cell array of timestamps for each signal in the data sourceSourceName— The name of the data sourceSourceParams— A structure containing fields with information required to load the data source
This code shows the loadSource method for the
vision.labeler.loading.PointCloudSequenceSource class. This method
performs these actions.
Check that the point cloud sequence has the correct extension and save the information required for reading the point clouds into a
fileDatastoreobject.Set the
Timestampproperty of the data source object.If timestamps are loaded from a workspace variable (Timestamps =
From workspace), then the method setsTimestampto the timestamps stored in thesourceParamsinput.If timestamps are derived from the point cloud sequence itself (Timestamps =
Use Default), then the method setsTimestampto adurationvector of seconds, with one second per point cloud.
Validate the loaded point cloud sequence.
Set the
SignalNameproperty to the name of the data source folder.Set the
SignalTypeproperty to thePointCloudsignal type.Set the
SourceNameandSourceParamsproperties to thesourceNameandsourceParamsoutputs, respectively.
function loadSource(this, sourceName, sourceParams) % Load file ext = {'.pcd', '.ply'}; this.Pcds = fileDatastore(sourceName,'ReadFcn', @pcread, 'FileExtensions', ext); % Populate timestamps if isempty(this.Timestamp) if isfield(sourceParams, 'Timestamps') setTimestamps(this, sourceParams.Timestamps); else this.Timestamp = {seconds(0:1:numel(this.Pcds.Files)-1)'}; end else if ~iscell(this.Timestamp) this.Timestamp = {this.Timestamp}; end end import vision.internal.labeler.validation.* checkPointCloudSequenceAndTimestampsAgreement(this.Pcds,this.Timestamp{1}); % Populate signal names and types [~, folderName, ~] = fileparts(sourceName); this.SignalName = makeValidName(this, string(folderName), "pointcloudSequence_"); this.SignalType = vision.labeler.loading.SignalType.PointCloud; this.SourceName = sourceName; this.SourceParams = sourceParams; end
Method to Read Frames
The last required method that you must define is the readFrame
method. This method reads a frame from a signal stored in the data source. The app calls
this method each time you navigate to a new frame. The index to a particular timestamp
in the Timestamp property is passed to this method.
This code shows the readFrame method for the
vision.labeler.loading.PointCloudSequenceSource class. The method
reads frames from the point cloud sequence by using the pcread function.
function frame = readFrame(this, signalName, index) if ~strcmpi(signalName, this.SignalName) frame = []; else frame = pcread(this.Pcds.Files{index}); end end
You can also define any additional private properties that are specific to loading
your data source. The source-specific methods for the
vision.labeler.loading.PointCloudSequenceSource class are not shown
in this example but you can view them in the class file.
Use Predefined Data Source Classes
This example showed how to use the
vision.labeler.loading.PointCloudSequenceSource class to help you
create your own custom class. This table shows the complete list of data source classes
that you can use as starting points for your own class.
| Class | Data Source Loaded by Class | Command to View Class Source Code |
|---|---|---|
vision.labeler.loading.VideoSource | Video file | edit vision.labeler.loading.VideoSource |
vision.labeler.loading.ImageSequenceSource | Image sequence folder | edit vision.labeler.loading.ImageSequenceSource |
vision.labeler.loading.VelodyneLidarSource | Velodyne packet capture (PCAP) file | edit vision.labeler.loading.VelodyneLidarSource |
vision.labeler.loading.RosbagSource | Rosbag file | edit vision.labeler.loading.RosbagSource |
vision.labeler.loading.PointCloudSequenceSource | Point cloud sequence folder | edit vision.labeler.loading.PointCloudSequenceSource |
vision.labeler.loading.CustomImageSource | Custom image format | edit vision.labeler.loading.CustomImageSource |