2016-06-21 16 views
0

Lassen Sie die Größe meiner Matrix A ist sx x sy x sz. Ich möchte eine Matrix erhalten B (mit der gleichen Größe wie A), wo das Element von B bei (x,y,z) den Durchschnitt der n x n x n Submatrix aus der gleichen Position bei A extrahiert.Schnelle Mittelung von 3D-Submatrizen in Matlab

Wie kann ich es tun?

Ich weiß, ich kann dies mit convn oder mit 3 for Schleifen tun, aber es wird sehr langsam sein.

Die Matrix A der Größe 200 x 200 x 150 ist in double Präzision auf meinem Rechner, wenn ich n = 9 brauche dauert etwa 20 bis 30 Sekunden.

+0

"Convn" ist wahrscheinlich der schnellste Weg, dies zu tun, wenn Ihnen das zu langsam ist, dann haben wir wahrscheinlich nicht viel zu empfehlen. – Suever

+1

Versuchen Sie, GPU auszunutzen, wenn es für Sie verfügbar ist. GPUs zeichnen sich durch Windungen aus. –

+0

Können Sie die Spezifikationen Ihrer Maschine angeben? Für mich dauert es im Durchschnitt etwa 1 Sekunde ... was ich für die relativ große Menge an Daten und den von Ihnen angegebenen Kernel für ziemlich schnell halte. Es kann einfach sein, dass Ihre Maschine die Leistung einschränkt. – rayryeng

Antwort

3

Verwenden Sie imfilter aus der Image Processing Toolbox. imfilter ist im Wesentlichen eine optimierte Faltungs-und Korrelationspipeline, die die Intel Integrated Performance Primitives nutzt. So wie ein einfacher Test, lassen Sie uns eine zufällige double Präzision 200 x 200 x 150 3D-Matrix erstellen, und wir wollen den Durchschnitt von 9 x 9 x 9 Pixel Nachbarschaften, wie Sie finden, sagte:

A = rand(200,200,150); 
kernel = (1/9^3)*ones(9,9,9); 
B = imfilter(A, kernel); 

Das eigentlich läuft recht schnell auf meiner Maschine. Meine Spezifikationen sind ein MacBook Pro mit 16 GB RAM mit einem 2,3 GHz Intel Core i7 Prozessor.

Nur Neugier zu befriedigen, habe ich timeit zu Zeit, wie lange dieser Vorgang dauert, wenn Sie den Kernel und die Matrix zuzuordnen:

A = rand(200,200,150); 
kernel = (1/9^3)*ones(9,9,9); 
B = imfilter(A, kernel); 
t = timeit(@() imfilter(A, kernel)); 

Im Durchschnitt der obige Code läuft für etwa 1,1393 Sekunden:

>> t 

t = 

    1.1393 

Wenn Sie nicht zu GPUs migrieren, ist dies für mich der schnellste Weg, den Sie jemals bekommen werden ... vor allem, weil Sie 150 Schichten von 200 x 200 2D Daten haben, die Sie mit jedem Punkt sammeln müssen 9 x 9 x 9 Volumen Elemente.