user1809923
user1809923

Reputation: 1255

Fast indexing into data array

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

Answers (2)

user1809923
user1809923

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

rahnema1
rahnema1

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

Related Questions