Reputation: 1255
Situation:
I have a data array of uint8 (e.g. uint8(zeros(24*30000,1))) which encodes 30000 points of 24 byte each. Say, I have an indice vector into this data array for example 1:2:30000. I know want to efficiently create the correct data array for the points referred to in the indice vector. This situation occurs for example when trying to remove points from a 'sensor_msgs/PointCloud2'-message with the Robotics System Toolbox.
Solution
Up to now, my solution is like this
startIndices = (pointIndices-1) * double(pointCloud_out.PointStep) + 1;
endIndices = pointIndices * double(pointCloud_out.PointStep);
indices = zeros(pointCloud_out.RowStep,1);
for ii = 1:numel(pointIndices)
indices((ii-1)*pointCloud_out.PointStep+1 : ii*pointCloud_out.PointStep) = startIndices(ii):endIndices(ii);
end
pointCloud_out.Data = pointCloud_in_msg.Data(indices);
where pointIndices is the above mentioned indice vector and pointCloud_out.PointStep encodes how many byte there are for one point (above 24). This solution however takes about 1.5s on my machine which is faaaaaar to long.
Question:
Can you think of any (very) fast solution to do this?
Upvotes: 0
Views: 76
Reputation: 1255
Came up with this solution:
pointsInCols = reshape(pointCloud_in_msg.Data,pointCloud_in_msg.PointStep,[]);
pointCloud_out.Data = reshape(pointsInCols(:,pointIndices),[],1);
First the data array is reshaped such that each column corresponds to one point. Then we take all the points we are interested in and reshape again. This solution takes about 0.003 s on my PC.
Upvotes: 0
Reputation: 15837
You can use bsxfun
indices = reshape(bsxfun(@plus, startIndices , (0:pointCloud_out.PointStep-1).'),[],1);
Values of (0:PointStep-1)
is added to each member of startIndices
Assumed startIndices
has size 1 * n
Upvotes: 1