AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kreise und Linien Erkennen , jetzt mit FMX (LINUX)

Ein Thema von bernhard_LA · begonnen am 11. Jun 2020 · letzter Beitrag vom 21. Jun 2020
Antwort Antwort
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#1

Kreise und Linien Erkennen , jetzt mit FMX (LINUX)

  Alt 11. Jun 2020, 16:06
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}
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.093 Beiträge
 
Delphi 12 Athens
 
#2

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

  Alt 11. Jun 2020, 17:17
Ich würde versuchen nicht für jedes Pixel Map,Unmap aufzurufen,
und womöglich auch den übergeordneten Caller optimieren.
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#3

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

  Alt 15. Jun 2020, 23:28
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
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#4

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

  Alt 15. Jun 2020, 23:51
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....
  Mit Zitat antworten Zitat
striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
207 Beiträge
 
Delphi 10.4 Sydney
 
#5

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

  Alt 16. Jun 2020, 08:43
Wie sieht es denn aus, wenn du es in der FMX-Version auch mit Scanlines versuchst (TBitmapData.GetScanline).
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.093 Beiträge
 
Delphi 12 Athens
 
#6

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

  Alt 16. Jun 2020, 11:52
nicht immer kann ich den Caller wie im Beispiel oben optimieren
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.
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#7

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

  Alt 21. Jun 2020, 00:10
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
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#8

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

  Alt 21. Jun 2020, 02:21
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.
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.062 Beiträge
 
Delphi XE2 Professional
 
#9

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

  Alt 21. Jun 2020, 20:12
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
Angehängte Dateien
Dateityp: zip Detect.zip (3,32 MB, 5x aufgerufen)
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:14 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