2017-01-30 6 views
0

Situation:schnelle Indizierung in Datenarray

I ein Datenfeld von uint8 (z.B. uint8 (Nullen (24 * 30000,1))), die jeweils 30000 Punkte von 24 Byte kodiert. Sagen wir, ich habe einen Indice-Vektor in dieses Datenfeld zum Beispiel 1: 2: 30000. Ich weiß, dass ich effizient das korrekte Datenarray für die Punkte erstellen möchte, auf die im Indice-Vektor Bezug genommen wird. Diese Situation tritt beispielsweise auf, wenn Sie versuchen, Punkte aus einer 'sensor_msgs/PointCloud2'-Nachricht mit der Robotics System Toolbox zu entfernen.

Lösung

Bis jetzt ist meine Lösung wie diese

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); 

wo pointIndices ist die oben erwähnte indice Vektor und pointCloud_out.PointStep kodiert, wie viele Byte dort für einen Punkt sind (siehe oben 24). Diese Lösung dauert jedoch etwa 1,5 Sekunden auf meiner Maschine, die zu lang ist.

Frage:

Können Sie sich jede (sehr) schnellen Lösung, dies zu tun?

+0

Ich bin ein wenig verwirrt über das, was Sie fragen. Was ist los mit 'pointCloud (:, Indizes)'? – Suever

+0

@Suever: Das Datenfeld der PointCloud (-2 Nachricht) ist eine m x 1 Matrix hier – user1809923

Antwort

1

können Sie bsxfun verwenden

indices = reshape(bsxfun(@plus, startIndices , (0:pointCloud_out.PointStep-1).'),[],1); 

Werte von (0:PointStep-1) jedem Mitglied von startIndices

startIndices Angenommene hinzugefügt wird, hat eine Größe 1 * n

+0

funktioniert! Musste zu indices = umformen (bsxfun (@plus, startIndices, (0: ​​double (pointCloud_out.PointStep) -1)) ', [], 1); weil meine StartIndices nx1 sind – user1809923

0

mit dieser Lösung Kam:

pointsInCols = reshape(pointCloud_in_msg.Data,pointCloud_in_msg.PointStep,[]); 
pointCloud_out.Data = reshape(pointsInCols(:,pointIndices),[],1); 

Zuerst wird das Datenfeld so umgestaltet, dass jede Spalte einem Punkt entspricht. Dann nehmen wir alle Punkte, an denen wir interessiert sind, und formen uns neu. Diese Lösung benötigt ca. 0,003 s auf meinem PC.