gusucode.com > vision工具箱matlab源码程序 > vision/pcdownsample.m
function ptCloudOut = pcdownsample(ptCloudIn, varargin) %PCDOWNSAMPLE Downsample a 3-D point cloud. % ptCloudOut = PCDOWNSAMPLE(ptCloudIn, 'random', percentage) % returns a downsampled point cloud with random sampling without % replacement. ptCloudIn and ptCloudOut are pointCloud objects. % percentage specifies the portion of the input to be returned. % % ptCloudOut = PCDOWNSAMPLE(ptCloudIn, 'gridAverage', gridStep) % returns a downsampled point cloud using box grid filter. gridStep % specifies the size of a 3-D box. Points within the same box are merged % to a single point in the output. Their color and normal properties are % averaged accordingly. This method better preserves the shape of the % point cloud. % % ptCloudOut = PCDOWNSAMPLE(ptCloudIn, 'nonuniformGridSample', % maxNumPoints) returns a downsampled point cloud using a nonuniform box % grid filter. maxNumPoints must be at least 6, and specifies the maximum % number of points in a grid box. The method randomly selects a single % point from each box. This method will automatically fill in the normal % property of ptCloudOut object if the normal is not already provided. % % Notes % ----- % - The best use of nonuniformGridSample method is to apply it as a % preprocessing step to pcregrigid when the 'pointToPlane' metric is % used. % - An important property of nonuniformGridSample algorithm is that the % normals are computed on the original data prior to downsampling. The % downsampled output preserves the more accurate normals. % % Class Support % ------------- % ptCloudIn and ptCloudOut must be pointCloud object. % % Example 1: Downsample a point cloud with box grid filter % -------------------------------------------------------- % ptCloud = pcread('teapot.ply'); % % % Set the 3D resolution to be 0.1-by-0.1-by-0.1 % gridStep = 0.1; % ptCloudA = pcdownsample(ptCloud, 'gridAverage', gridStep); % % % Visualize the downsampled data % figure % pcshow(ptCloudA); % % % Compare to downsampling with fixed step size % stepSize = floor(ptCloud.Count/ptCloudA.Count); % indices = 1:stepSize:ptCloud.Count; % ptCloudB = select(ptCloud, indices); % % figure % pcshow(ptCloudB); % % Example 2: Remove redundant points % ---------------------------------- % % Create a point cloud with all points sharing the same coordinates % ptCloud = pointCloud(ones(100,3)); % % % Set the 3-D resolution to be a small value % gridStep = 0.01; % % The output now only has one unique point % ptCloudOut = pcdownsample(ptCloud, 'gridAverage', gridStep); % % See also pointCloud, pcshow, pcregrigid, pctransform % Copyright 2014 The MathWorks, Inc. % % References % ---------- % Fran鏾is Pomerleau, Francis Colas, Roland Siegwart, St閜hane Magnenat, % Comparing ICP variants on real-world data sets, Autonomous Robots, % April 2013, Volume 34, Issue 3, pp 133-148 narginchk(3, 3); % Validate the first argument if ~isa(ptCloudIn, 'pointCloud') error(message('vision:pointcloud:notPointCloudObject', 'ptCloudIn')); end % Validate the method argument strMethod = validatestring(varargin{1}, {'random','gridAverage','nonuniformGridSample'}, mfilename); if strncmpi(strMethod, 'random', 1) % Validate the third argument percentage = varargin{2}; validateattributes(percentage, {'single','double'}, {'scalar', 'real', '>=', 0, '<=', 1}, mfilename, 'percentage'); K = round(ptCloudIn.Count*percentage); indices = vision.internal.samplingWithoutReplacement(ptCloudIn.Count, K); [points, color, normal] = subsetImpl(ptCloudIn, indices); elseif strncmpi(strMethod, 'gridAverage', 1) % Validate the third argument gridStep = varargin{2}; validateattributes(gridStep, {'single','double'}, {'scalar', 'real', 'positive'}, mfilename, 'gridStep'); % Remove invalid points to determine a bounded volume pc = removeInvalidPoints(ptCloudIn); rangeLimits = [pc.XLimits, pc.YLimits, pc.ZLimits]; % Apply grid filter to each property [points, color, normal] = visionVoxelGridFilter(pc.Location, ... pc.Color, ... pc.Normal, ... gridStep, rangeLimits); else % Validate the third argument maxNumPoints = varargin{2}; % The maximum number of points needs to be at least 6 because we need % to compute normals using PCA. validateattributes(maxNumPoints, {'single','double'}, {'scalar', 'real', 'integer', '>=', 6}, mfilename, 'maxNumPoints'); % Remove invalid points to determine a bounded volume pc = removeInvalidPoints(ptCloudIn); % Apply nonuniformGridSample filter to location property and generate % normal if it does not exist if ~isempty(pc.Normal) indices = visionNonUniformVoxelGridFilter(pc.Location, maxNumPoints); [points, color, normal] = subsetImpl(pc, indices); else [indices, normal] = visionNonUniformVoxelGridFilter(pc.Location, maxNumPoints); [points, color] = subsetImpl(pc, indices); end end ptCloudOut = pointCloud(points, 'Color', color, 'Normal', normal);