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

Rechenzeit Ellipse

 

x4ecro
Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.09.2010, 16:56     Titel: Rechenzeit Ellipse
  Antworten mit Zitat      
Hallo,
ich verusche mithilfe einer FOR-Schleife in eine Matrix (die später mal ein TIF-Bild sein wird; hier eine Matrix aus Einsen) beliebig viele Ellipsen einzufügen. Durch den Parameter cloud_cover reguliere ich, wieviel Prozent des Bildes inetwa durch Ellipsen ersetzt werden sollen.
Diese Methode funktioniert an und für sich auch sehr gut. Das Problem ist die Rechenzeit. Die Matrix des Satellitenbildes hat die Dimensionen 8000x7000 Pixel. Da jedes Pixel mit der FOR-Schleife 'besucht' wird, um eine Ellipse zu generieren und das ganze auch noch mehrfach abläuft, um auf (in diesem Beispiel) 5% dauert die ganze Sache Stunden.
Die Rechenzeit steigt bei dieser Methode quadratisch mit der Anzahl der Matrixelemente...

Meine Frage lautet daher:
Hat jemand eine Idee, wie man das ganze effizienter gestalten könnte?

Code:


%initilal Parameters
cloud_cover = 5;


dim = 500; %Dimension der NxN-Matrix;
Matrix = ones(dim,dim+200); %Matrix aus Einsen;

dim_x= size(Matrix,1);    
dim_y= size(Matrix,2);  

%sum of matrix elemnts before cloud simulation
sum_before = sum(sum(Matrix));
   
cloud_fraction = 0;  
 wb = waitbar(0,'Cloud Cover Simulation');
while cloud_fraction<cloud_cover
 
waitbar(cloud_fraction/cloud_cover,wb);
   
   
 x = (dim_x)*rand(1);
 y = (dim_y)*rand(1);
 
 
 
%Ellsipsenparameter, a=b -> Kreis
a= 10; %Ellipse semiaxis in y-direction
b= 10; %Ellipse semiaxis in x-direction

for i=1:dim_x
    for j=1:dim_y
    k = i-x;
    l = j-y;
    if k^2/a^2+l^2/b^2<1 %squared
        Matrix(i,j)=0;
    end
    end
end
%sum of matrix elemnts after cloud simulation
sum_after = sum(sum(Matrix));

%percentage of simulated clouds
cloud_fraction = 100-(sum_after/sum_before*100)

end

close(wb);
 


Besten Dank!
Private Nachricht senden Benutzer-Profile anzeigen


Linus
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 69
Anmeldedatum: 30.08.10
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 10.09.2010, 17:13     Titel: Re: Rechenzeit Ellipse
  Antworten mit Zitat      
Ok, fangen wir mal ganz einfach an...

Möglichkeit 1, die stupide Brechstange, wenn du die Parallel Computing Toolbox und einen Multicore Rechner hast: Parallelisier das Ganze. Schreib in deinen Code oben hin, wenn du z.B. einen Quadcore hast:
Code:

matlabpool open 4
 

Dan ersetze das äußere for durch ein parfor und probier mal aus.


Möglichkeit 2: Du setzt in jedem Durchlauf außen a und b neu, und in jedem inneren Loop (da wo es ganz kritisch ist), berechnest du a^2 und b^2. Setze a und b außerhalb des whiles, berechne a2 (oder nenns a_squared), für b auch, und spar dir 2mal quadrieren...


Möglichkeit 3: Vektorisieren. Das wird, wenn es klappt, viel rausholen. Hab gerade noch nicht genau genug drüber nachgedacht, tu ich aber noch. Du würdest versuchen, die for-Schleifen ganz weg zu lassen, und logische Indizes zu benutzen. Kanns gerade nich genau erklären, entweder du ahnst in welche Richtung ich will, oder ich muss das nochmal selbst versuchen...


Möglichkeit 4: Mehr vorberechnen. Die Ellipsengleichung wird ja dauernd aufgerufen, alles was sich ändert sind x und y. Du solltest, da a und b konstant sind, dir eine Art "Ellipsen-Maske" vorberechnen. Die wird dann nur darüber gelegt, wo sie gebraucht wird, ganz ohne Loop. Wie einen kleinen Stempel, der auf dein großes Bild immer draufgepresst wird, an zufälligen Locations. Das würde am allerallermeisten bringen. Ist klar was ich meine? Auch da fehlt natürlich jetzt die konkrete Umsetzung von mir.
_________________

RWTH - Mindstorms NXT Toolbox - free & open source
Private Nachricht senden Benutzer-Profile anzeigen
 
x4ecro
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.09.2010, 18:38     Titel:
  Antworten mit Zitat      
Zitat:
Dan ersetze das äußere for durch ein parfor und probier mal aus.


--> ??? Error: The variable Matrix in a parfor cannot be classified.

Zitat:
Möglichkeit 2: Du setzt in jedem Durchlauf außen a und b neu, und in jedem inneren Loop (da wo es ganz kritisch ist), berechnest du a^2 und b^2. Setze a und b außerhalb des whiles, berechne a2 (oder nenns a_squared), für b auch, und spar dir 2mal quadrieren...


--> a und b werde deshalb neu berechnet, weil sie später einmal varriieren sollen für jede ellipse

zu den anderen varianten habe ich so erstmal keine vorstellung.

grüße
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 10.09.2010, 22:35     Titel: Re: Rechenzeit Ellipse
  Antworten mit Zitat      
Dear x4ecro,

Vektorisieren:
Code:

x = (dim_x)*rand(1);
y = (dim_y)*rand(1);
a = 10; %Ellipse semiaxis in y-direction
b = 10; %Ellipse semiaxis in x-direction

k = (1 - x:dim_x - x) ;
l = transpose((1 - y:dim_y - y)) ;
Matrix = bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) < 1;
 


Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 12.09.2010, 23:03     Titel: Re: Rechenzeit Ellipse
  Antworten mit Zitat      
Hallo x4ecro,

Mein Code produziert tatsächlich eine andere Ausgabe als Deiner. Um eine equivalente Ausgabe zu erreichen, muss aber einfach nur Vorder- und Hintergrund vertauscht werden!
Code:

% Alt: Matrix = bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) < 1;
% Neu:
Matrix = bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) >= 1;
 

Entspricht das eher Deinen Erwartungen??

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
x4ecro
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.09.2010, 23:35     Titel:
  Antworten mit Zitat      
Leidr läuft das Programm dann nicht mehr korrekt. Bei meiner Variante wird eine Ellipse erzeugt, geschaut, wieviel Prozent des Bildes dann mit Ellipsen gefüllt sind und das Ganze so oft wiederholt, bis der Grenzwert (hier 5%) überschritten wurde. Bei deiner Variante wird zwar eine Ellipse eingefügt, aber beim nächsten Durchlauf der While-Schleife wieder überschrieben, so, dass der Prozentsatz immer ungefähr gleich bleibt und nicht ansteigt. Wie kann ich das denn beheben?

Hier nochmal der Quellcode:

Code:


clear
clear all
close all

%initilal Parameters
cloud_cover = 5;
%cluster_factor = 0;
mean_cloud_size = 10;
size_variation = 10;

%Matrix=imread('C:\Users\Robert\Desktop\LT51940242007197MOR00\test_subset.tif', 'TIFF');
dim = 500; %Dimension der NxN-Matrix;
Matrix = ones(dim,dim); %Matrix aus Einsen;

dim_x= size(Matrix,1);    
dim_y= size(Matrix,2);  

%sum of matrix elemnts before cloud simulation
sum_before = sum(sum(Matrix));
   
cloud_fraction = 0;  
 wb = waitbar(0,'Cloud Cover Simulation');
 
 h=1;
while cloud_fraction<cloud_cover
 
   waitbar(cloud_fraction/cloud_cover,wb);
   
 x = (dim_x)*rand(1);
 y = (dim_y)*rand(1);
 
a= mean_cloud_size+(rand(1)*size_variation); %Ellipse semiaxis in y-direction
b= mean_cloud_size+(rand(1)*size_variation); %Ellipse semiaxis in x-direction

coordinates(h,1)=x;
coordinates(h,2)=y;

% for i=1:dim_x
%     for j=1:dim_y
%     k = i-x;
%     l = j-y;
%     if k^2/a^2+l^2/b^2<1 %squared
%         Matrix(i,j)=0;
%     end
%     end
% end


k = (1 - x:dim_x - x) ;
l = transpose((1 - y:dim_y - y)) ;
Matrix = bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) >= 1;

%sum of matrix elemnts after cloud simulation
sum_after = sum(sum(Matrix));

%percentage of simulated clouds
cloud_fraction = 100-(sum_after/sum_before*100)

h=h+1;

end

close(wb);

scatter(coordinates(:,1),coordinates(:,2));

%Image of the Matrix
imagesc(Matrix);
title('Cloud Simulation');
colorbar;
colormap('Gray');
axis equal,
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 12.09.2010, 23:43     Titel: Re: Rechenzeit Ellipse
  Antworten mit Zitat      
Hallo x4ecro,

Ja, mein Code produziert nur eine einzelne Ellipse. Ich hielt den Transfer daraus die Summe mehrerer Ellipsen zu erstellen, für leicht. Dafür gibt es viele Möglichkeiten, z.B.:
Code:
Matrix = false;  % Initialisieren

% Schleife ...
  Matrix = or(Matrix, bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) >= 1);
% Schleifen-Ende.

Oder:
Code:

Matrix = ones(dim,dim);
...
  Matrix(bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) < 1) = 0;
...

Ich hatte mit der BSXFUN-Zeile Deine beiden Schleifen ersetzt und den Einbau in Dein Gesamt-Programm Dir überlassen.

Viele Grüße, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
x4ecro
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.09.2010, 23:54     Titel:
  Antworten mit Zitat      
Das funktioniert, danke!

Code:
Matrix(bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) < 1) = 0;


Die Rechenzeit sinkt tatsächlich beträchtlich
Private Nachricht senden Benutzer-Profile anzeigen
 
x4ecro
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 13.09.2010, 10:34     Titel:
  Antworten mit Zitat      
Guten Morgen,

Nun habe ich folgendes Problem...

so lange die Matrix quadratisch ist, funktioniert die Funktion bsxfun wunderbar. Wenn ich jedoch eine nicht quadratische Matrix einlade (in diesem Fall 7321*8251) geht das ganze nicht mehr und das Ergebnis sind 1 Pixel breite streifen, anstelle der gewollten Ellipsen Sad

bsxfun_quadratisch.PNG
 Beschreibung:

Download
 Dateiname:  bsxfun_quadratisch.PNG
 Dateigröße:  6.01 KB
 Heruntergeladen:  377 mal
bsxfun_nicht quadratisch.PNG
 Beschreibung:

Download
 Dateiname:  bsxfun_nicht quadratisch.PNG
 Dateigröße:  228.7 KB
 Heruntergeladen:  450 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 14.09.2010, 20:12     Titel:
  Antworten mit Zitat      
Hallo x4ecro,

BSXFUN funktioniert auch mit unterschiedlich langen Vektoren, wenn das Ergebnis also rechteckig ist.

Bitte überprüfe nochmal Deinen Code und ob die Ellipsen nur in der Ausgabe plattgequetscht werden, im ungestuachten Plot aber einwandfrei sind.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
x4ecro
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.09.2010, 20:23     Titel:
  Antworten mit Zitat      
Jan S hat Folgendes geschrieben:
Hallo x4ecro,

BSXFUN funktioniert auch mit unterschiedlich langen Vektoren, wenn das Ergebnis also rechteckig ist.

Bitte überprüfe nochmal Deinen Code und ob die Ellipsen nur in der Ausgabe plattgequetscht werden, im ungestuachten Plot aber einwandfrei sind.

Gruß, Jan


Hi,

Was müsste ich in diesem Fall ändern? Ich habe nochmal die gleiche Berechnung als Bilder eingefügt für:

1. Eine Matrix mit 500*500 Pixeln
2. Eine Matrix mit 500*600 Pixeln

Hierzu habe ich folgenden Code verwendet:
Die Achsen des Diagramms sind als gleich skaliert.

Code:

clear
clear all
close all

%initilal Parameters
cloud_cover = 20;
%cluster_factor = 0;
mean_cloud_size = 10;
size_variation = 10;

dim = 500; %Dimension der NxN-Matrix;
%Matrix = ones(size(img,1),size(img,2)); %Matrix aus Einsen;
Matrix= ones(dim,dim+100);
dim_x= size(Matrix,1);    
dim_y= size(Matrix,2);  

%sum of matrix elemnts before cloud simulation
sum_before = sum(sum(Matrix));
   
cloud_fraction = 0;  
 wb = waitbar(0,'Cloud Cover Simulation');
 
 h=1;
while cloud_fraction<cloud_cover
 
   waitbar(cloud_fraction/cloud_cover,wb);
   
 x = (dim_x)*rand(1);
 y = (dim_y)*rand(1);
 
a= mean_cloud_size+(rand(1)*size_variation); %Ellipse semiaxis in y-direction
b= mean_cloud_size+(rand(1)*size_variation); %Ellipse semiaxis in x-direction

coordinates(h,1)=x;
coordinates(h,2)=y;



k = (1 - x:dim_x - x) ;
l = transpose((1 - y:dim_y - y)) ;
Matrix(bsxfun(@plus, k .^ 2 / a^2, l .^ 2 / b ^ 2) < 1) = 0;
 

%sum of matrix elements after cloud simulation
sum_after = sum(sum(Matrix));

%percentage of simulated clouds
cloud_fraction = 100-(sum_after/sum_before*100)

h=h+1;

end

close(wb);

%Image of the Matrix
imagesc(Matrix);
title('Cloud Simulation');
colorbar;
colormap('Gray');
axis equal,
 


Danke, R.

cloud_500by600.png
 Beschreibung:

Download
 Dateiname:  cloud_500by600.png
 Dateigröße:  10.54 KB
 Heruntergeladen:  427 mal
cloud_500by500.png
 Beschreibung:

Download
 Dateiname:  cloud_500by500.png
 Dateigröße:  8.08 KB
 Heruntergeladen:  410 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 14.09.2010, 22:27     Titel:
  Antworten mit Zitat      
Hallo x4ecro,

fällt Dir das Muster in dem Bild auf? Sieht ganz so aus, als habest Du X- und Y-Koordinaten beim logical-indexing vertauscht, woraufhin die Ellipsen in den Spalten verschoben würden. Versuche das ganze doch mal mit einer Ellipse und viel weniger Pixeln, so dass Du Dir die Ausgabe der BSXFCN-Funktion noch im Command-Window betrachten kannst.

Viel Erfolg, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
x4ecro
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 13
Anmeldedatum: 10.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.09.2010, 22:49     Titel:
  Antworten mit Zitat      
Hallo Jan,

das ist scheinbar tatsächlich des Pudels Kern gewesen. (siehe Bild)

Vielen Dank!

Robert

Jan S hat Folgendes geschrieben:
Hallo x4ecro,

fällt Dir das Muster in dem Bild auf? Sieht ganz so aus, als habest Du X- und Y-Koordinaten beim logical-indexing vertauscht, woraufhin die Ellipsen in den Spalten verschoben würden. Versuche das ganze doch mal mit einer Ellipse und viel weniger Pixeln, so dass Du Dir die Ausgabe der BSXFCN-Funktion noch im Command-Window betrachten kannst.

Viel Erfolg, Jan


cloud_final.png
 Beschreibung:

Download
 Dateiname:  cloud_final.png
 Dateigröße:  196.02 KB
 Heruntergeladen:  382 mal
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.