Import Point Cloud Data For Deep Learning
To use point cloud data in deep learning workflows, the data must be read in from its raw form in a data set into MATLAB. In this example, we are working with the Sydney Urban Objects Dataset [1]. This example shows how to use MATLAB Datastores to read in and represent data for deep learning.
Download Sydney Urban Objects Dataset
The Sydney Urban Objects data is 122 MB in its uncompressed form and may take a few moments to download depending on your network connection speed.
sydneyUrbanObjectsPath = downloadSydneyUrbanObjects(tempdir());
Define Datastore For Point Cloud Data
Create a datastore to load point cloud data from Sydney Urban Objects, along with associated object labels.
ds = loadSydneyUrbanObjectsData(sydneyUrbanObjectsPath);
Read and display the first observation from the Datastore.
data = preview(ds)
data=1×2 cell array
{1×1 pointCloud} {[4wd]}
disp(data)
{1×1 pointCloud} {[4wd]}
The output of the read and preview methods of the Datastore is a cell array in which the first column is a pointCloud object and the second column is the associated class label. A pointCloud object can be visualized using the pcshow function.
figure pcshow(data{1}) title(string(data{2}))
References
[1] Alastair Quadros, James Underwood, Bertrand Douillard; 2013. Sydney Urban Objects Dataset.
Supporting Functions
function datasetPath = downloadSydneyUrbanObjects(dataLoc) % This function downloads the Sydney Urban Objects tar archive to tempdir % provides as output the location of where the data was saved. if nargin == 0 dataLoc = pwd(); end dataLoc = string(dataLoc); url = "http://www.acfr.usyd.edu.au/papers/data/"; name = "sydney-urban-objects-dataset.tar.gz"; if ~exist(fullfile(dataLoc,'sydney-urban-objects-dataset'),'dir') disp('Downloading Sydney Urban Objects Dataset...'); untar(url+name,dataLoc); end datasetPath = dataLoc.append('sydney-urban-objects-dataset'); end function ds = loadSydneyUrbanObjectsData(datapath,folds) % loadSydneyUrbanObjectsData Create datastore with point clouds and % associated categorical labels for Sydney Urban Objects dataset. % % ds = loadSydneyUrbanObjectsData(datapath) returns a datastore that % represents point clouds and associated categories for the Sydney Urban % Objects dataset. The input, datapath, is a string or char array which % represents the path to the root directory of the Sydney Urban Objects % Dataset. % % ds = loadSydneyUrbanObjectsData(___,folds) optionally allows % specification of desired folds that you wish to be included in the % output ds. For example, [1 2 4] specifies that you want the first, % second, and fourth folds of the Dataset. Default: [1 2 3 4]. if nargin < 2 folds = 1:4; end datapath = string(datapath); path = fullfile(datapath,'objects',filesep); % For now, include all folds in Datastore foldNames{1} = importdata(fullfile(datapath,'folds','fold0.txt')); foldNames{2} = importdata(fullfile(datapath,'folds','fold1.txt')); foldNames{3} = importdata(fullfile(datapath,'folds','fold2.txt')); foldNames{4} = importdata(fullfile(datapath,'folds','fold3.txt')); names = foldNames(folds); names = vertcat(names{:}); fullFilenames = append(path,names); ds = fileDatastore(fullFilenames,'ReadFcn',@extractTrainingData,'FileExtensions','.bin'); end function dataOut = extractTrainingData(fname) [pointData,intensity] = readbin(fname); [~,name] = fileparts(fname); name = string(name); name = extractBefore(name,'.'); labelNames = ["4wd","bench","bicycle","biker",... "building","bus","car","cyclist","excavator","pedestrian","pillar",... "pole","post","scooter","ticket_machine","traffic_lights","traffic_sign",... "trailer","trash","tree","truck","trunk","umbrella","ute","van","vegetation"]; label = categorical(name,labelNames); dataOut = {pointCloud(pointData,'Intensity',intensity),label}; end function [pointData,intensity] = readbin(fname) % readbin Read point and intensity data from Sydney Urban Object binary % files. % names = ['t','intensity','id',... % 'x','y','z',... % 'azimuth','range','pid'] % % formats = ['int64', 'uint8', 'uint8',... % 'float32', 'float32', 'float32',... % 'float32', 'float32', 'int32'] fid = fopen(fname, 'r'); c = onCleanup(@() fclose(fid)); fseek(fid,10,-1); % Move to the first X point location 10 bytes from beginning X = fread(fid,inf,'single',30); fseek(fid,14,-1); Y = fread(fid,inf,'single',30); fseek(fid,18,-1); Z = fread(fid,inf,'single',30); fseek(fid,8,-1); intensity = fread(fid,inf,'uint8',33); pointData = [X,Y,Z]; end