WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Eigene Funktion sehr langsam?!

 

finalcu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.09.2010, 10:53     Titel: Eigene Funktion sehr langsam?!
  Antworten mit Zitat      
Hallo Zusammen,

ich habe eine Funktion zur Bestimmung der Orientierung eines Roboters geschrieben. Die Funktion bekommt einen Bildausschnitt vom Roboter (ein vorheriger Algorithmus ist dafuer zustaendig), worauf ein Pfeil, der die Laufrichtung des Roboters repraesentiert, zu sehen ist. Als zusaetzliches Argument dien ein Template des Pfeils in Nullposition. Die Funktion rotiert nun den Bildausschnitt und berechnet fuer jede Rotation (1 bis 360) die Summe der Differenzen der beiden Bilder.

Der Algorithmus funktioniert einwandfrei, nur die Funktion fuer die Bestimmung der Orientierung laesst bezueglich Geschwindigkeit zu wuenschen uebrig. Mein Rechner braucht dafuer ca. 3.5 Sekunden, was mir fuer den nicht allzuhohen Rechenaufwand sehr langsam vorkommt.

Koennte jemand die Funktion vielleicht auf seinem Rechner ausfuehren und die Ausfuehrungszeit messen?

Hier ist die Funktion:
Code:

function [orientation,min_value] = find_orientation(img_arrow,sub_img,xc,yc)
[height,width] = size(img_arrow);
%rot_img = img_arrow;
SAD = zeros(1,360);
for a=1:360
    for x=1:width
        for y=1:height
            %move window
            xp = xc+x-floor(width/2);
            yp = yc+y-floor(height/2);
            %rotate window
            r = sqrt((xc-xp)^2+(yc-yp)^2);
            X_R = [cos(a*pi/180) -sin(a*pi/180);sin(a*pi/180) cos(a*pi/180)]*[xp-xc;yp-yc]+[xc;yc];
            xr = round(X_R(1));
            yr = round(X_R(2));
            %rot_img(y,x) = sub_img(yr,xr);
            SAD(a) = SAD(a) + abs(double(img_arrow(y,x))-double(sub_img(yr,xr)));
        end
    end
end
[min_value,orientation] = min(SAD);
 


Zwei Bilder sind angehaengt: img_arrow (Template) und sub_img (Bildausschnitt). Diese muessen zuerst mit imread eingelesen und mit rgb2gray konvertiert werden.

Die Funktion wird dann wie folgt aufgerufen:
Code:

find_orientation(img_arrow,sub_img,34,34)


Vielen Dank!

sub_img.png
 Beschreibung:

Download
 Dateiname:  sub_img.png
 Dateigröße:  6.58 KB
 Heruntergeladen:  449 mal
img_arrow.png
 Beschreibung:

Download
 Dateiname:  img_arrow.png
 Dateigröße:  1.02 KB
 Heruntergeladen:  402 mal


Ajax
Forum-Century

Forum-Century


Beiträge: 176
Anmeldedatum: 09.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.09.2010, 12:48     Titel:
  Antworten mit Zitat      
Versuch mal a als Vektor zu definieren. Damit kannst du die äußerste Schleife einsparen. Wenn ich das richtig überblicke, müsste das ganz einfach funktionieren (evtl. die Zeile mit XR weglassen und beide Gleichungen gleich in xr und yr stecken).
Private Nachricht senden Benutzer-Profile anzeigen
 
finalcu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.09.2010, 20:41     Titel:
  Antworten mit Zitat      
Macht das denn überhaupt einen Unterschied? MATLAB muss intern ja auch jedes einzelne Element des Vektors in einer Schleife durchgehen...
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 16.09.2010, 21:33     Titel:
  Antworten mit Zitat      
Hallo finalcu,

ja, das macht im Allgemeinen einen dramatischen Unterschied. Matlab ist dafür konzipiert mit "Mat"rizen zu arbeiten, Vektoren sind daher grundsätzlich ebenfalls 2-dimensional (1xN oder Mx1).
Schleifen mit Skalaren sind dagegen in Matlab eher lahm.

Dein Programm berechnet sehr viele Zahlen mehrfach, z.B.:
[code]for y=1:height
...
xp = xc+x-floor(width/2);
...
end[code]
Dabei hängt xp gar nicht von der inneren Schleife ab. Ziehe es also lieber davor und spare Zeit.
"sin(a*pi/180)" muss auch nicht doppelt berechnet werden, ebenso wie der entsprechende COS.
"r = sqrt((xc-xp)^2+(yc-yp)^2);" wird gar nicht benötigt.
Die ständige Umwandlung in DOUBLE ist viel effizienter, wenn Du sie ausserhalb der Schleifen einmal durchführst.

Es bleibt also auch nOch eine Menge zu verbessern bovor Du das vektorisierst. Aber erst mit Matrix-Methoden wird das in Matlab so richtig schnell.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.