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

Flächenberechnung eines Polygons mit polyarea()

 

Localhorst
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 86
Anmeldedatum: 18.02.08
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 09:55     Titel: Flächenberechnung eines Polygons mit polyarea()
  Antworten mit Zitat      
Hallo Forum,

ich möchte die Fläche eines Polygons mit polyarea() berechnen. Das Polygon bekommt in einer While Schleife pro Durchlauf zwei Koordinatenpaare dazu. Nach jedem Durchlauf soll die Fläche neu berechnet und geschaut werden ob die Fläche bereits größer ist als ein eingestellter Schwellwert. (Ich möchte das benutzen, um die Fläche zwischen zwei kurvigen Konturlinien in möglichst gleich große Flächenteile aufzuteilen.)




Die Teilflächen sind nicht wirklich gleich groß Rolling Eyes


Hier mal ein Ausschnitt bei Schleifendurchlauf 60. Jede blaue Linie meint eine Traverse. Die rote Fläche ist ein patch(). Im nächsten Durchlauf werden die X,Y Koordinaten von Start und Endpunkt der nächsten Traverse zu dem Patch hinzugefügt. Und immer so weiter bis der Schwellwert überschritten wird.




Ich habe den Quellcode mal auskommentiert und auch eine lauffähige Version als zip angehängt. Das Programm läuft auch, nur verstehe ich das Verhalten von polyarea (Zeile:5Cool ab dem Schleifendurchlauf 64 nicht.(conditional breakpoint zeile 72 (i==60), und dann folgende Durchläufe betrachten)
Die Darstellung des Polygons mit patch() zeigt, dass das Polygon wie gewünscht größer wird nur steigt die Fläche des Polygons nicht mehr an. Das Polygon wird um eine senkrechte Linie nach untern verlängert, kann es sein, dass dies zu einem Problem bei der Flächenberechnung führt?

Das ganze Programm ist bis jetzt nur für mich zum testen und in keinem Punkt optimiert oder besonders gut strukturiert. Bitte versteht es als einen Test!

Vielen Dank für eure Hilfe!

Code:

function plot_profiles()
pause('on');
load('traversen.mat');

if ~exist('img','var')
    %img=imread('B05_1621.tif');
    img=ones(5000,6976);
end
% Darstellen des (leeren) Bildes
imshow(img);
x_all=[];
y_all=[];
% Darstellen aller Traversen die aus der Datei traversen.mat eingelesen
% wurden (Traverse meint hier immer eine der mit line(x,y) dargestellten
% Linien. Die Linien wurden zwischen zwei (hier nicht mehr sichtbaren)
% Konturlinien erzeugt. Die Konturlinien umschließen eine Biologische
% Struktur die später Bildanalytisch untersucht werden soll
for i=1:size(prof,2)
    x=[prof(1,i).startx,prof(1,i).endx];
    y=[prof(1,i).starty,prof(1,i).endy];
    line(x,y);
    x_all=[x_all,x];
    y_all=[y_all,y];
end
pause
% gesamt fläche
hin=[prof(1,:).startx;prof(1,:).starty];
zurueck=[prof(1,:).endx;prof(1,:).endy];
zurueck=fliplr(zurueck);
hin_zurueck=[hin zurueck];
%patch(test(1,:),test(2,:),'r');
%sum_area = gesamtfläche zwischen den Konturlinien
sum_area= polyarea(hin_zurueck(1,:),hin_zurueck(2,:));
% gesamtfläche soll in zB 30 gleichgroße Teile unterteilt werden
% part_area= zB 1/30 der Gesamtfläche. Dient als Schwellwert, wenn dieser
% Wert überschritten wurde soll ein neuer Patch eröffnet werden
part_area=sum_area/30;

% quick and dirty initialisierung einiger Variablen
step=1; % nur für die abwechselnde Färbung der Patches
start_temp=[]; % Vektoren mit den X und Y Koordinaten der Startpunkte der Traversen
end_temp=[]; % Vektoren mit den X und Y Koordinaten der Endpunkte der Traversen
i=1;
% Hauptschleife über alle Traversen die aus der Datei traversen.mat
% eingelesen wurden
while i<size(prof,2)
    % das Patch wird in jedem Durchlauf vergrößert (bzw. ein neues um eine
    % Traverse größers Patch wird erzeugt). Altes kleineres wird deswegen
    % gelöscht
    h = findobj(gca,'Type','patch','Tag','tmp');
    delete(h);
    % Zusammenbau des Vektors für die Patch Generierung
    start_temp=[start_temp;prof(1,i).startx,prof(1,i).starty];
    end_temp=[end_temp;prof(1,i).endx,prof(1,i).endy];
    end_flip=flipud(end_temp); % einmal flippen, da Patch sonst verdreht
    sum_temp=[start_temp;end_flip]; % Vektor mit X,Y von Start und Endpunkten der Traversen
    % Berechnen der Fläche des aktuell erzeugten Patches
    temp_area=polyarea(sum_temp(:,1),sum_temp(:,2));
    % Darstellung des Patches
    h_patch=patch(sum_temp(:,1),sum_temp(:,2),'r','Marker','o','MarkerFaceColor','y');
    % Tag setzen um temp. Patches später wieder löschen zu können
    set(h_patch,'Tag','tmp');
    i=i+1;
    %disp(['Summe:' num2str(sum_area)]);
    %disp(['Thres:' num2str(part_area)]);
    disp(['Loop Ind:' num2str(i)]);
    disp(['TempA:' num2str(temp_area)]);
    disp('------------------');
    % Abfragen ob die Fläche des aktuellen Patches schon größer als der
    % geplante Schwellwert ist und falls ja Farbe ändern und anderen Tag
    % setzen
    if temp_area>part_area
        if mod(step,2)==0
            set(h_patch,'FaceColor','b');
        else
            set(h_patch,'FaceColor','g');
        end
        set(h_patch,'Tag','final');
        i=i-1;
        start_temp=[];
        end_temp=[];
        step=step+1;
    end
   
end

pause('off');

 


polyarea.zip
 Beschreibung:
Lauffähige Version

Download
 Dateiname:  polyarea.zip
 Dateigröße:  494.92 KB
 Heruntergeladen:  365 mal
Private Nachricht senden Benutzer-Profile anzeigen


MaFam
Forum-Meister

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 18.12.2012, 10:49     Titel:
  Antworten mit Zitat      
Hallo,

ich habe den Code jetzt nicht im Detail studiert, aber diese Zeile:
Code:

sum_area= polyarea(hin_zurueck(1,:),hin_zurueck(2,:));
 


Ist hier sichergestellt, dass die Sortierung der Punkte stimmt? Du solltest zunächst eine Seite des Gebildes aufzählen, dann die andere Seite, also beispielsweise "hin rechts" und dann "zurück links". Zum Abschluss des Polygons noch den Anfangsknoten am Ende aufführen.

Grüße, Marc
Private Nachricht senden Benutzer-Profile anzeigen
 
Localhorst
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 86
Anmeldedatum: 18.02.08
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 10:52     Titel:
  Antworten mit Zitat      
Hi,

ja, das sollte so sein, deswegen lasse ich mir das Polygon auch immer wieder ausgeben in der Figure, da ich genau in dem Punkt viele Fehler hatte und das Polygon immer wieder verdreht war.
Aber momentan wird es mir richtig angezeigt, auch alle Eckpunkte werden richtig angezeigt.

Ich baue den gesamten Vektor extra deswegen in den Zeilen davor zusammen.
Code:
% gesamt fläche
hin=[prof(1,:).startx;prof(1,:).starty]; % xy Koordinaten der Hinpunkte
zurueck=[prof(1,:).endx;prof(1,:).endy]; % xy Koordinaten der Zurück Punkte
zurueck=fliplr(zurueck); % dann einmal flippen, damit die Reihenfolge stimmt
hin_zurueck=[hin zurueck]; % und wieder zusammen bauen
%patch(hin_zurueck(1,:),hin_zurueck(2,:),'r'); % zeigt den richtigen Patch, der durch alle hin und zurück Punkte geht


Gruß
Localhorst
Private Nachricht senden Benutzer-Profile anzeigen
 
MaFam
Forum-Meister

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 18.12.2012, 11:27     Titel:
  Antworten mit Zitat      
Ich würde in der Schleife das gleiche machen wie hier
Code:

hin=[prof(1,:).startx;prof(1,:).starty]; % xy Koordinaten der Hinpunkte
zurueck=[prof(1,:).endx;prof(1,:).endy]; % xy Koordinaten der Zurück Punkte
zurueck=fliplr(zurueck); % dann einmal flippen, damit die Reihenfolge stimmt
hin_zurueck=[hin zurueck]; % und wieder zusammen bauen
 


nur dass du : durch ein 1:i ersetzt. Der Schwellwert wäre dann k*part_area, wenn du beim k-ten patch bist.
Private Nachricht senden Benutzer-Profile anzeigen
 
Localhorst
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 86
Anmeldedatum: 18.02.08
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 12:16     Titel:
  Antworten mit Zitat      
Hi und danke das du schon mal drüber geschaut hast.

Ich habe deine Änderung eingebaut. Es ändert aber leider nichts an der Tatsache, dass die polyarea() Fläche ab einem Loopindex von 64 nicht mehr steigt obwohl das paralell dazu abgebildete patch deutlich größer wird.

Ich spare mir durch deine Idee zwei Variablen, was natürlich schon mal gut ist, aber das Problem besteht leider immer noch.

Gruß
Localhorst
Private Nachricht senden Benutzer-Profile anzeigen
 
Localhorst
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 86
Anmeldedatum: 18.02.08
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 12:56     Titel:
  Antworten mit Zitat      
Hi,

ich habe nun eine Lösung gefunden. Leider verstehe ich sie nicht.

Die Werte aus der Datei traversen.mat wurden als uint16 ausgelesen. Wenn ich nun die Werte in double konvertiere funktioniert die ganze Sache?

Warum?



Code:
   %test
    hin=[prof(1,start_temp:i).startx;prof(1,start_temp:i).starty];
    zurueck=[prof(1,start_temp:i).endx;prof(1,start_temp:i).endy];
    zurueck=fliplr(zurueck);
    hin_zurueck=[hin zurueck];
    hin_zurueck=double(hin_zurueck);
    % Berechnen der Fläche des aktuell erzeugten Patches
    temp_area=polyarea(hin_zurueck(1,:),hin_zurueck(2,:));
Private Nachricht senden Benutzer-Profile anzeigen
 
MaFam
Forum-Meister

Forum-Meister


Beiträge: 799
Anmeldedatum: 02.05.12
Wohnort: ---
Version: R2009b
     Beitrag Verfasst am: 18.12.2012, 13:02     Titel:
  Antworten mit Zitat      
Da wäre ich jetzt nicht drauf gekommen, obwohl ich kürzlich ein ähnliches Problem hatte. Die internen Operationen in polyarea, wozu auch die Division gehört, führen zu Stellenfehlern. Teilt man zwei uint-Datentypen, fallen die Nachkommastellen weg. Mit einer Konvertierung in double wird das Problem natürlich behoben.
Private Nachricht senden Benutzer-Profile anzeigen
 
Localhorst
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 86
Anmeldedatum: 18.02.08
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 13:30     Titel:
  Antworten mit Zitat      
Vielen Dank für dein Feedback!
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.