Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Kreise und Linien Erkennen , jetzt mit FMX (LINUX) (https://www.delphipraxis.net/204613-kreise-und-linien-erkennen-jetzt-mit-fmx-linux.html)

bernhard_LA 11. Jun 2020 15:06

Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
ich versuche mich gerade ein einer Portierung des VCL Projekts zur Kreis und Linien Erkennung https://sourceforge.net/projects/houghtransforma/
von VCL auf FMX

die Funktion IsPixel() prüft ob der Mittelwert aus r,g,b-Kanal größer als ein Schwellwert ist und gibt dafür ein true / false zurück.
Unter VCL gehts perfekt, Schnell ( < Sekunde) , die FMX
Variante rechnet ca. 10 min :-( .... und vermutlich noch nicht mal richtig :-(


Delphi-Quellcode:
{$IFDEF FRAMEWORK_VCL}

function IsPixel(xpos, ypos: integer; aBitmap: TBitMap;
  ThresHold: integer): boolean;
var
  p: pbyteArray;
  r, g, b, mean: integer;
begin

  aBitmap.PixelFormat := pf24bit;

  if (ypos <= aBitmap.Height - 1) and (xpos <= aBitmap.Width - 1) then

  begin
    p := aBitmap.ScanLine[ypos];

    r := p[3 * xpos];
    g := p[3 * xpos + 1];
    b := p[3 * xpos + 2];
    mean := ((round(r) + round(g) + round(b)) div 3);

    if (mean > ThresHold) then
      result := true
    else
      result := false;

  end
  else
  begin
    result := false
  end;

end;

{$ENDIF}
{$IFDEF FRAMEWORK_FMX}

function IsPixel(xpos, ypos: integer; aBitmap: TBitMap;
  ThresHold: integer): boolean;
var
  r, g, b, mean: integer;

  bitdata: TBitmapData;

  C: TAlphaColor;
begin
  if (aBitmap.Map(TMapAccess.Read, bitdata)) then
    try

      C := bitdata.GetPixel(xpos, ypos);

      r := TAlphaColorRec(C).r;
      g := TAlphaColorRec(C).g;
      b := TAlphaColorRec(C).b;

      mean := round((r + g + b) / 3);

      if (mean > ThresHold) then
        result := true
      else
        result := false;

    finally
      aBitmap.Unmap(bitdata);
    end;
end;

{$ENDIF}

Rollo62 11. Jun 2020 16:17

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
Ich würde versuchen nicht für jedes Pixel Map,Unmap aufzurufen,
und womöglich auch den übergeordneten Caller optimieren.

bernhard_LA 15. Jun 2020 22:28

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
gibt es in FMX eine schnellere Funktion , Option ohne Map, Unmap auf ein Pixel zuzugreifen .... ?

nicht immer kann ich den Caller wie im Beispiel oben optimieren :evil:

Harry Stahl 15. Jun 2020 22:51

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
Sowohl die VCL- als auch die FMX Lösung könnte man nur akzeptieren, wenn man insgesamt nur ein Pixel prüfen müsste, z.B. um herauszubekommen, welcher Farbwert gerade unter der aktuellen Mausposition ist.

Aber ich gehe mal davon aus, dass bei Deiner Aufgabenstellung ein paar mehr Pixel zu prüfen sind.

Dann ist es doch naheliegend, einmal den Zugriff auf die Bitmap zu nehmen (also if (aBitmap.Map(TMapAccess.Read, bitdata)) then) und dann alle relevanten Pixel der Bitmap auf einmal durchzulaufen (und nicht nur eines zu prüfen) und dann den Zugriff auf die Bitmap wieder freizugeben....

striderx 16. Jun 2020 07:43

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
Wie sieht es denn aus, wenn du es in der FMX-Version auch mit Scanlines versuchst (TBitmapData.GetScanline).

Rollo62 16. Jun 2020 10:52

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
Zitat:

Zitat von bernhard_LA (Beitrag 1467374)
nicht immer kann ich den Caller wie im Beispiel oben optimieren :evil:

Dann würde vielleicht helfen ein "Shadow-Bitmap" zu führen, das vielleicht auch nur ein TAlphaColor array Buffer ist.
Der dann nur bei Bedarf am Stück in das echte Bitmap kopiert wird.
Macht aber wohl nur Sinn wenn die Bitmaps nicht zu groß werden, und Du nicht dauernd neue Bilder laden musst.

Bitmaps in FMX kann man auch über die Texture-Komponenten verwalten, vielleicht gibt es da auch was Passendes für Dich.

bernhard_LA 20. Jun 2020 23:10

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
was macht eigentlich die map Funktion genau ?
im Task Manager ist meine GPU auf 80 % für 10 min

der VCL code hat eine Laufzeit im Sekunden Bereich :-)

TiGü 21. Jun 2020 01:21

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
Wenn du Map und Unmap außerhalb deiner Schleife aufrufen würdest, dann wäre das auch Ruckzuck erledigt.
Ansonsten würde einfach ein Debuggen mit Debug-DCUs und F7 dir schon weiterhelfen zu erkennen, dass ein ständiges hin- und herkopieren des Bitmaps aus dem Grafikkartenspeicher in den CPU erreichbaren RAM pro (!) einzelnen Pixel nicht die schnellste Lösung ist.

Amateurprofi 21. Jun 2020 19:12

AW: Kreise und Linien Erkennen , jetzt mit FMX (LINUX)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Die Sache hat mich interessiert.
Ich habe mir deshalb das Demo-Projekt einmal angeschaut und, nachdem ich auf einige Ungereimtheiten stieß, ein eigenes Projekt erstellt, das im Anhang zu finden ist.

Zu den langen Laufzeiten:
Die sind darauf zurückzuführen, dass
1) Für die Prüfung der Pixel eine eigene Funktion aufgerufen wird, die ihrerseits mit TBitmap.ScanLine einen Zeiger auf die Pixeldaten holt, die RGB-Werte liest und prüft, ob der Mittelwert der RGB-Werte 1/3 Threshold übersteigt.
2) In den Prozeduren Hough_CircleDetection und Hough_LineDetection wiederholt cos(theta*PI/max_theta) und sin(theta*PI/max_theta) berechnet werden. Sinnvoller ist es, die Sinus und Cosinus Werte für alle 0 bis 360 Theta Werte (bzw. 0 bis 180 bei LineDetection) in Tabellen zu stellen und bei Bedarf daraus zu lesen.

Mit dem Programm im Anhang können Bilder geladen werden und Linien- / Kreiserkennungen durchgeführt werden.
Die daraus resultierenden Bitmaps können als Bitmap oder JPEG gespeichert oder als Bitmap ins Clipboard kopiert werden.
Die Original-Prozeduren stehen in der Unit "Unit_HoughTransformation".
Die von mir erstellten Prozeduren stehen in der Unit "Detect_Transformation".
Die Prozeduren zur Kreis- und Linienerkennung sich auch als Assembler-Prozeduren vorhanden, für 32Bit und 64Bit.
Das Ganze ist für VCL. Wie das für FMX angepasst werden kann/muss weiß ich nicht, weil ich mich nie mit FMX beschäftigt habe.
Bitte keine Rückfragen zur Funktionsweise der Kreis-/ Linienerkennung. Ich habe mich damit nicht beschäftigt sondern nur auf Basis der Original-Codes meine Codes erstellt.

Wenn ein Bild geladen ist, kann die Linienerkennung mit F4 (Original-Prozeduren), Ctrl-F4 (Neue Prozeduren) oder Shift-F4 (Assembler-Prozeduren) gestartet werden.
Die Kreiserkennung wird nach dem gleichen Schema mit F5 gestartet.
Mit F11 können anschließend die gemessenen Ausführungszeiten angezeigt werden.
Für das Bild "circle_many.bmp" wurden für die Erkennung von Kreisen folgende Zeiten gemessen:

Original 883.2 ms
Neu 47.90 ms
Assembler 25.03 ms

Tipps:
Die Dateinamen geladener Bilder werden in einer Liste gespeichert und im Menu Datei > "Bild laden" Menu-Einträge erzeugt, mit denen diese Dateien erneut geladen werden können.
Mit Strg-F2 kann das zuletzt geladene Bild erneut geladen werden.
Wenn der Eintrag "Menu > Optionen > Einstellungen bei Programmende speichern" markiert ist, werden die Einstellungen und die Liste der geladenen Dateien in der Datei "DetectSettings.bin" im Programmverzeichnis gespeichert und beim nächsten Programmstart geladen.

Das Original Projekt enthält mehrere Fehler. So werden zum Beispiel die bei der Erkennung von Linien und Kreisen erstellten Daten vor der nächsten Erkennung nicht gelöscht, was zur Folge hat, dass die Daten die Summen aller Erkennungen enthalten.
Ich habe das (für die Original-Routinen) bewusst so belassen.
Wenn der Eintrag "Daten vor Erkennung löschen" markiert ist, werden diese Daten vor einer Erkennung gelöscht und enthalten dann korrekte Daten.

Im Anhang befinden sich
Die Source-Codes meines Projektes und des Original-Projektes.
Die .exe Dateien meines Projektes und des Original-Projektes.
Die zum Original-Projekt gehörenden Bilder


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz