MATLAB Answers

How to graphicall​y/interact​ively select region of interest from 3D point cloud data

16 views (last 30 days)
Qasim Nazir
Qasim Nazir on 25 Nov 2019
Edited: Qasim Nazir on 26 Nov 2019
I am working with 3d point cloud data and interested in graphically selecting regions of interest from MATLAB figures. A possible scenario could be changing the view to one of the planes (e.g. XY plane) and drawing some contours or geometric shapes using cursor as shown below. Then selected datapoints should be stored in a workspace variable.
I found something similar for images (2d figures) but not sure how to that for 3d point cloud data.
Is something like this can be done in MATLAB?


Sign in to comment.

Accepted Answer

Bjorn Gustavsson
Bjorn Gustavsson on 25 Nov 2019
In newer versions of matlab there seems to be just such a feature, see: ROI.CUBOID
For older versions of matlab (I vaguely recall) there might be versions of ginput with extended 3-D capabilities on the file exchange: ginput-extensions


Qasim Nazir
Qasim Nazir on 26 Nov 2019
Thanks for the help.
I was able to draw a roi.Cuboid and roi.Rectangle. Since I am considering complete z-range (-inf,inf) so I set the deafult view to XY-plane and found roi.Rectangle to be easier to use. So first step is done, I am able to get corrdinates for my roi (or geometrically define a roi).
Next question is how to select (filter) only those points from point cloud object that lie inside roi. There is a function findPointsInROI for point cloud object but it takes roi in a different way [xmin, xmax, ymin, ymax, zmin, zmax]. That will not work if my rectangle is rotated at some angle.
This is my code so far.
ax = pcshow(ptCloud,'VerticalAxisDir','Down');
ax.View = [0,-90]; % XY-plane default view
%% roi Selection (use one from following)
% roi.Cuboid
h = images.roi.Cuboid(ax,'Rotatable','z');
roi = [min(h.Vertices)', max(h.Vertices)'];
% roi.Rectangle
h = images.roi.Rectangle(ax,'Rotatable',true);
roi = [min(h.Vertices)', max(h.Vertices)';-inf,inf];
%% subset of ptCloud
selected_indices = findPointsInROI(ptCloud,roi);
sub_ptCloud = select(ptCloud,selected_indices);
Bjorn Gustavsson
Bjorn Gustavsson on 26 Nov 2019
Well since you select all points based on their x and y coordinates it doesn't matter what other values (z and other possibly associated to the point), and you have a 2-D problem. For that you can let your selected edge-points define an arbitrary polygon and use the inpolygon. It would happily take arbitrary points and build a polygon (can be self-intersecting and have wholes inside and whatnot), so your rotated rectangular area should be "a walk in the park". Just check the help and documentation for inpolygon and you'll have your solution completed in minutes.
Qasim Nazir
Qasim Nazir on 26 Nov 2019
It worked out for me, thanks for your help. Final code is here.
ax = pcshow(ptCloud);
ax.View = [0,90];
%% draw roi
roi = images.roi.Polygon(ax) ;
%% select points inside roi
x = ptCloud.Location(:,1);
y = ptCloud.Location(:,2);
mask = inROI(roi,x,y);
sub_ptCloud = select(ptCloud,mask);

Sign in to comment.

More Answers (0)

Sign in to answer this question.