AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia FreePascal Grafiken erkennen. Library ?
Thema durchsuchen
Ansicht
Themen-Optionen

Grafiken erkennen. Library ?

Ein Thema von stiftII · begonnen am 4. Mai 2012 · letzter Beitrag vom 10. Mai 2012
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.553 Beiträge
 
Delphi 12 Athens
 
#1

AW: Grafiken erkennen. Library ?

  Alt 4. Mai 2012, 21:40
man kann jedes Pixel auslesen, man kann aber auch scanline verwenden (schneller)
Kommt drauf an, ob der Algorithmus es erlaubt sich im Bitmap horizontal zu bewegen.
Auch bei Scanline kann man ist man nicht auf eine horizontale Bearbeitung beschränkt.

- vorher in einem Pointer-Array alle Scanlines zwischenspeichern und schon hat man eine Art zweidimensionales Array

- sich den Zeiger auf die letzte Scanline holen (diese Bitmaps werden von unten nach oben gespeichert) und schon kann man über eine Art eindimensionales Array drauf zugreifen (alle Zeilen hintereinander)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Grafiken erkennen. Library ?

  Alt 4. Mai 2012, 22:01
xD
Genau dies habe ich implementiert und warte nun auf seine Antwort auf meine letzte Frage ^^ (+SAD, einfach und langsam)
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
bernhard_LA
Online

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

AW: Grafiken erkennen. Library ?

  Alt 5. Mai 2012, 08:52
der Algorithmus zum Finden eines Suchbildes in einer großen Vorlage ist :
NORMALIZED CROSS CORRELATION - BZW. FAST NCC

unter http://sourceforge.net/projects/nccfastncc/ gibt eine Demo Application dazu in DELPHI.
Für unser Testbild benötigt die Version auf Source forge ~ 30 sec auf meinem Laptop, aktuell haben wir eine optimierte Version von FAST NCC entwickelt, die Suche
geht ca. 500 x schneller, dh. ist aber aktuell kein Open Source code. Falls Di ein Suchprojekt bearbeitest reicht Dir event. die Public Version des Algorithmuses.

Geändert von bernhard_LA ( 5. Mai 2012 um 08:55 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Grafiken erkennen. Library ?

  Alt 5. Mai 2012, 13:13
Hier, die einfache Variante mit SAD (Sum of Absolute Differences (siehe Wikipedia))

Delphi-Quellcode:
function findPicture(const Source, Picture: TBitmap): TPoint;
type
  TPRGBTripleRow = Array of PRGBTriple;
var
  SourceScanlineRow : TPRGBTripleRow;
  PictureScanlineRow : TPRGBTripleRow;
  function getRGBDifference(const ColorA, ColorB: PRGBTriple): Integer;
  begin
    Result := abs(ColorA.rgbtBlue - ColorB.rgbtBlue) +
              abs(ColorA.rgbtGreen - ColorB.rgbtGreen) +
              abs(ColorA.rgbtRed - ColorB.rgbtRed);
  end;
  function getPColor(const ScanlineRow: TPRGBTripleRow; const X, Y: Integer): PRGBTriple;
  begin
    Result := PRGBTriple(Integer(ScanlineRow[y]) + x * 3);
  end;
  procedure buildScanlineRows;
  var
    y: Integer;
  begin
    SetLength(SourceScanlineRow, Source.Height);
    for y := 0 to Source.Height - 1 do SourceScanlineRow[y] := Source.ScanLine[y];
    SetLength(PictureScanlineRow, Picture.Height);
    for y := 0 to Picture.Height - 1 do PictureScanlineRow[y] := Picture.ScanLine[y];
  end;
  function _findPicture: TPoint;
  var
    x, y, i, j : Integer;
    SAD : Integer;
    curSAD : Integer;
  begin
    SAD := -1; // not assigned
    for y := 0 to Source.Height - Picture.Height do
      for x := 0 to Source.Width - Picture.Width do
      begin
        curSAD := 0;
        for j := 0 to Picture.Height - 1 do
          for i := 0 to Picture.Width - 1 do
            inc(curSAD, getRGBDifference(getPColor(SourceScanlineRow, x + i, y + j), getPColor(PictureScanlineRow, i, j)));
        if (SAD = -1) or (curSAD < SAD) then
        begin
          SAD := curSAD;
          Result := Point(x, y);
          if SAD = 0 then Exit;
        end;
      end;
  end;
begin
  if (Picture.Width > Source.Width) or (Picture.Height > Source.Height) or
     (Picture.PixelFormat <> pf24bit) or (Source.PixelFormat <> pf24bit) then
    Result := Point(-1, -1)
  else
  begin
    buildScanlineRows;
    Result := _findPicture;
  end;
end;
Edit: Das liefert die linke obere Ecke des Bereiches. Der Bereich hat klarerweise dieselbe Dimension wie "Picture"
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG

Geändert von Aphton ( 5. Mai 2012 um 14:18 Uhr)
  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 17:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz