AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Pixelerkennung, Kreativität gesucht die mir fehlt!
Thema durchsuchen
Ansicht
Themen-Optionen

Pixelerkennung, Kreativität gesucht die mir fehlt!

Ein Thema von Pixel · begonnen am 23. Aug 2016 · letzter Beitrag vom 27. Aug 2016
Antwort Antwort
Seite 2 von 2     12   
hanvas

Registriert seit: 28. Okt 2010
166 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Pixelerkennung, Kreativität gesucht die mir fehlt!

  Alt 24. Aug 2016, 16:33
Ich würde zunächst ein Array in den Dimensionen des Bildes anlegen, als Datentyp würde ich vermutlich Byte wählen, kann aber sein das Integer, wenn es auf Geschwindigkeit ankommt, ggf. besser wäre.

Anschließend würde ich an allen Positionen die im Bild der Suchfarbe entsprechen eine 1 im Array setzen, an allen anderen Positionen eine 0. Das Ergebnis bis hierhin ist praktisch Binärbild das die zu bearbeitenden Umrisse, die Buchstaben und die Paralellogramme des gesuchten Balkens enthalten.

Anschließend würde ich eine Liste der "verbundenen Komponenten" erstellen. Die nachfolgenden Prozeduren sollten nebenbei auch noch ein Labeling durchführen, das heißt jedem Umriss im erzeugten "Binärbild" eine andere Nummer, beginnend mit 2 zuordnen. Die erzeugte Liste enthält ein Objekt welches die Anzahl der zusammenhängenden Pixel speichert, das Rechteck für jeden Umriss das den Umriss gerade noch umschließt und das Label das mit dem Urisse in unseren Array korrospondiert.

Einfach mal so hingeschrieben, ungetestet, keine Garantie auf Korrektheit, beim dargestellten Problem (und s/w Bild) sollte die rekursive Version funktionieren.

Delphi-Quellcode:

const nr = YYYY; // Dimension in y
      nc = XXXX; // Dimension in x

type TData : Array[0..nr,0..nc] of byte;

      // Bitte selbst implementieren
      TObjectInfo = class(TObject) // oder record
      private
       FExtends : TRect;
       FLabel : Integer;
       FSize : Integer;
      public
       Constructor Create(aSize, aLabel : Integer; minX,minY,maxX,maxY : Integer );
      property
       Size : Integer
        read FSize;
      property
       R : TRect
         read FExtends
      property
       label : Integer
         read FLabel;
      end;

function ConnectedArea ( var data : TData; y,x : Integer; Searched : Integer= 1; Visited: Integer = 2; var minX,minY,maxX,maxY ) : Integer;
var v : Integer;
begin
  if ( y< nr ) and
     ( y >= 0 ) and
     ( x < nc ) and
     ( x >= 0 ) then
  begin
   v := Data[y,x];
   if (v=Searched) and //
      (v<>visited) then
      begin
       if (minX>x) then
           minX:= x;
       if (minY>y ) then
           minY:= y;
       if (maxX>x) then
           maxX := x;
       if (maxY>y) then
           maxY := y;
       result := 1;
       Data[y,x] := visited;
       result := result + ConnectedArea ( img, y+1, x , Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y+1, x+1, Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y+1, x-1, Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y-1, x , Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y-1, x-1, Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y-1, x+1, Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y , x+1, Value, minx,miny,maxx,maxy );
       result := result + ConnectedArea ( img, y , x-1, Value, minx,miny,maxx,maxy );
      end else
      result := 0;
  end else result := 0;
end;

function ListConnected
  ( var Data : TData; zx1, zy1, zx2, zy2 : Integer ) : TList;
var i,j : Integer;
    a, cnt : LongInt;
    minx,miny,
    maxx,maxy : Integer;
begin
 result := TList.Create;
 cnt := 2;
 minx := maxInt;
 miny := maxInt;
 maxx := 0;
 maxy := 0;
 for j := zy1 to zy2 do
   for i := zx1 to zx2 do
     if ( Data[j,i] = 1 ) then
      begin
       cnt := cnt + 1;
       a := ConnectedArea ( Data, 1, cnt, j,i, minx,miny,maxx,maxy );
       if ( a > NOISE ) then begin
                               result.Add(TObjectInfo.Create(a,cnt,minx,miny,maxx,maxy);
                               minx := maxInt;
                               miny := maxInt;
                               maxx := 0;
                               maxy := 0;
                             end;
      end;
end;

Wenn man sich deine Beispielbilder ansieht fällt auf das der von dir gesuchte Balken aus nebeneinanderliegenden Paralellogrammen besteht. Die Bilder sind für mich zu klein um erkennen zu können ob sich die Paralellogramme berühren, ich gehe mal von nein aus.

Die einander nicht berührenden Paralellogramme würden in der erzeugten Liste als jeweils eigene Objekte zu finden sein. Die y Koordinate der jeweiligen Grundlinien sollte gleich, oder durch Darstellungsfehler unter Umständen um ein Pixel nach oben oder unten verschoben sein. Die Rechtecke die die Ausmaße beschreiben müssen überlappen. Solange also mindestens zwei Paralellogramme existieren musst Du eigentlich nur nach überlappenden Objekten mit praktisch gleichen Dimensionen an unterschiedlichen X Positionen, aber (nahezu) gleichen Y Positionen suchen und das Rechteck bilden das alle Objekt die Du so findest einschließt.

[1] Wenn Du meine Prozedur von vertikal zuerst auf horizontal umstellst dann werden die Objekte sogar in der richtigen Reihenfolge erzeugt was das suchen und finden noch einfacher macht.

cu Ha-Jö

Geändert von hanvas (24. Aug 2016 um 16:36 Uhr) Grund: cnt muss mit 2 beginnen
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#12

AW: Pixelerkennung, Kreativität gesucht die mir fehlt!

  Alt 24. Aug 2016, 17:43
Muss die Erkennung wirklich rein visuell sein? Weiß nicht genau, inwiefern sowas vom rechtlichen Standpunkt her in Deutschland erlaubt ist, aber ich würde mir die Koordinaten der Spieler einfach aus dem Arbeitsspeicher des Spiels auslesen.

Andere (aber deutlich kompliziertere) Alternative:
Reverse das Netzwerkprotokoll, schalte deine eigene Anwendung als Proxy dazwischen und lese die Koordinaten einfach aus dem Daten-Stream aus. Das hatten wir damals bei einem bekannten Valve Spiel mal erfolgreich als PoC implementiert.
So wie ich Blizzard kenne, wird deren berühmt-berüchtigte Anti-Cheat Software "Warden" teil des Spiels sein. Und auf Gefummel im Prozessraum des Spiels reagiert dieser sofort. Rein rechtlich ist das wohl kein Problem, aber rein rechtlich ist es auch keines, wenn Blizzard dann einem die Nutzung ihrer Server untersagt.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#13

AW: Pixelerkennung, Kreativität gesucht die mir fehlt!

  Alt 24. Aug 2016, 18:21
Muss die Erkennung wirklich rein visuell sein? Weiß nicht genau, inwiefern sowas vom rechtlichen Standpunkt her in Deutschland erlaubt ist, aber ich würde mir die Koordinaten der Spieler einfach aus dem Arbeitsspeicher des Spiels auslesen.

Andere (aber deutlich kompliziertere) Alternative:
Reverse das Netzwerkprotokoll, schalte deine eigene Anwendung als Proxy dazwischen und lese die Koordinaten einfach aus dem Daten-Stream aus. Das hatten wir damals bei einem bekannten Valve Spiel mal erfolgreich als PoC implementiert.
So wie ich Blizzard kenne, wird deren berühmt-berüchtigte Anti-Cheat Software "Warden" teil des Spiels sein. Und auf Gefummel im Prozessraum des Spiels reagiert dieser sofort. Rein rechtlich ist das wohl kein Problem, aber rein rechtlich ist es auch keines, wenn Blizzard dann einem die Nutzung ihrer Server untersagt.
Trotzdem mal aus Interesse: Wie findet man denn "einfach" die Koordinaten der Spieler im Arbeitsspeicher? Ich hab sowas mal vor Jahren bei emulierten GBA-Spielen gemacht, aber die sind ja auch sehr hardwarenah und primitiv. Bei modernen PC-Spielen ist doch wahrscheinlich alles dynamisch sonstwo allokiert.

Was die visuelle Erkennung angeht: OpenCV ist extrem mächtig. Wenn es mit irgendwas geht, dann damit. Aber braucht natürlich viel Einarbeitung. Ich kann dir da auch nicht helfen, weil ich da nur mal so ganz am Rande was mit zu tun hatte.
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#14

AW: Pixelerkennung, Kreativität gesucht die mir fehlt!

  Alt 24. Aug 2016, 18:41
Schönes Thema

Zum "Abgreifen" von (Geometrie)Informationen für/von 3D Programmen eigenen sich spezielle DirectX-"kompatible"-Grafiktreiber. VMware hat es vorgemacht das und wie es mit nur 10..15% Geschwindigkeitsverlust innerhalb von VMs funktioniert. (Sollte ein "Bot" der Plan sein, würde ich auch völlig ohne Effekte darstellen lassen, so hat man viel weniger optische Beeinflussung der 3D Objekte)

Aber zurück zum "SourceHack" der 3D-Informationen... das ist schon daher besser, weil man echte "Tiefe" hat und behält, also nicht versuchen muss aus der in 2D dargestellen 3D Szene sich diese Information wieder zu rekonstruieren.

Das "simulierte"Ansteuern von Maus&Tastatur macht doch heute keiner mehr ohne HDI kompatibles Modul, was direkt von aussen als echtes Maus&Tastatur Interface die entsprechenden Sachen völlig ohne spezielle Ring0-Treiber macht.
Wenn ich zunächst neutrale Bot's für "beliebige" 2D Sachen entwickeln wollte, würde ich das eventuell sogar völlig extern machen, also 2PCs... Kamera des zweiten PC mit meiner Software nimmt den Screen des ersten auf und steuert per HDI ein Mouse&Tastaturinterface für den ersten PC und kontrolliert "optisch" auch gleich die MousePosition, weil es gern mal passiert, das Programme die Mouse selbst versetzen und ein Bot ohne externe Rückkopplung dann Probleme bekommt.


=> nur zum Spass macht und entwickelt sowas aber keiner nebenbei/kostenlos... alles was mir da einfällt hätte mit der Umgehung von kommerziellen Nutzungseinschränkungen zu tun und wäre wenn man es gewinnorientiert zum eigenen Vorteil trotzdem macht definitiv illegal
  Mit Zitat antworten Zitat
Pixel

Registriert seit: 23. Aug 2016
26 Beiträge
 
#15

AW: Pixelerkennung, Kreativität gesucht die mir fehlt!

  Alt 24. Aug 2016, 19:10
@hanvas: Cool danke, ich möchte das zwar nicht 1:! so übernehmen wie du es da geschrieben hast aber ich werde auf jedenfall mit deiner Idee rumspielen! (und hier den Code dann posten)

@Medium: Das ist korrekt. Blizzard hat ihre eigene Anti cheat Abteilung und die sind definitiv nicht unfähig. Gut so! Wie du schon meintest - "finger weg vom Blizzard-RAM, denn sonst gibt's nen Bann!"

@Namenloser: Das kommt auf das Spiel an. Die Werte selbst (z.B. Spielerpositionen) sind zwar an dynamischen Adressen (99.99999%), aber man kann mit Hilfe von einigen Tools die statischen Pointer (also immer gleiche Adresse) finden und dann mittels Offsets zum gewünschten Wert (nzw. zur dynamischen Adresse) finden. Aber da die meisten Spiele das nicht wollen gibt es halt Sicherheitsvorkehrungen und da liegt dann die eigentliche Schwierigkeit.

@mensch72: Naja, wenn ich die Maus virtuell Bewegen will dann kann man SendInput() nutzen, die Funktion ruft widerum mouse_event() auf und diese widerum auf Ring0 w32k.sys NtUserSendInput(). mouse_event() z.B. sendet direkt in den Maus-Stream. Das heißt man müsste schon NtUserSendInput() hooken um herauszufinden ob die Mausbewegung physikalisch oder virtuell geschah. Wenn ich nicht falsch informiert bin, ist das so..

Geändert von Pixel (24. Aug 2016 um 19:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von bitsetter
bitsetter

Registriert seit: 17. Jan 2007
1.169 Beiträge
 
Turbo Delphi für Win32
 
#16

AW: Pixelerkennung, Kreativität gesucht die mir fehlt!

  Alt 27. Aug 2016, 07:16
Zitat:
Also fest steht Die Mitte der HP-Bar ist immer die Mitte des Kopfes, das heißt wenn man die Breite ermitteln könnte wäre die Sache schon getan, denn ich habe festgestellt:
Es sieht aber auf deinen letzten beiden Bildern so aus, als wenn sich die HP-Bar immer mittig vom Bildschirm befindet. Dann könnte man doch mit Hilfe das ersten linken Pixels der HP-Bar den letzten rechten Pixel und somit die Gesamtbreite berechen.

(rechter Pixel) = (Breite des Bildes) - (linker Pixel)
Gruß bitsetter
"Viele Wege führen nach Rom"
Wolfgang Mocker (geb. 1954), dt. Satiriker und Aphoristiker
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 16:17 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