Simpel "Pattern Recognition"

Tags:    c#

Hej der.

Problemet jeg står over for er ikke et problem som jeg ikke er i stand til at løse, men jeg kan ikke rigtig komme på den "smarte" måde at gøre det på.

Jeg har et "mønster" i form af et PNG billede (68x32px) hvor de irrelevante pixel har Alpha 0.

Jeg skal undersøge om dette mønster finde i et andet billede (screenshot) og få et koordinat retur så jeg ved hvor mønsteret befinder sig, hvis det findes.

Som allerede nævnt kan jeg sagtens komme på løsningsmodeller, men da dette kun er en lille del af an lang og kompliceret process, kunne jeg altså godt tænke mig at gøre det på den bedst tænkelige måde.

Jeg har naturligvis prøvet at søge på nettet, men jeg kan kun finde meget avancerede løsninger. Jeg er imidlertid kun interesseret i et 100% match, og således burde der være bedre og simplere metoder.

Jeg håber at i kan hjælpe.

På forhånd tak.

Edit:
her er links til test materiale.

http://www.myhideout.eu/temp/pattern.png
http://www.myhideout.eu/temp/test.png



Indlæg senest redigeret d. 01.03.2011 21:54 af Bruger #4414
9 svar postet i denne tråd vises herunder
0 indlæg har modtaget i alt 0 karma
Sorter efter stemmer Sorter efter dato
Jeg har tidligere lavet noget ignende i forbindelse med en Bot til at spille blackjack.

Det jeg gjorde var se se på hvor mange forksellige billeder der kan være på det sted på skærmen du skal tage et billede af. HVis ikke der kan være så mange. Kan du udvælge nogle forskellige pixels indenfor dit billede og så se på deres farve, og hvis farven på de pixels er som du forventer, så er dit billede rigtigt. Det er simpelt og vil virke



Jeg har tidligere lavet noget ignende i forbindelse med en Bot til at spille blackjack.

Det jeg gjorde var se se på hvor mange forksellige billeder der kan være på det sted på skærmen du skal tage et billede af. HVis ikke der kan være så mange. Kan du udvælge nogle forskellige pixels indenfor dit billede og så se på deres farve, og hvis farven på de pixels er som du forventer, så er dit billede rigtigt. Det er simpelt og vil virke


Jeg må erkende at jeg Ikke lige har fået fat i den røde tråd her, men ejg tror jeg har en god idé.

Anyway, det er vigtigt at bemærke at "mønsteret" kan befinde sig (eller ikke befinde sig) et hvilket som helst sted i et screenshot med varierende opløsning.

Jeg har naturligvis regnet ud hvordan det kan gøres rent teoretisk, selv om jeg må erkende at jeg har haft nogle mærkværdige "bugs" i praksis. Ja, jeg har ikke været inde i C# verdenen særlig længe, men det kommer nok nu da jeg er tvunget til at sætte mig ind i det.

Nuvel, tilbage til det åbenlyse metode som ganske enkelt involverer at find en pixel i "screenshot" som matcher første pixel i "pattern", når/hvis en sådan finde, tester man næste pixel i "screenshot" op imod næste pixel i "pattern". Hvis testen fejler først man er nået til enden af "pattern", fortsætter man naturligvis testen fra start af "pattern" indtil man har fundet et match eller er nået til enden af "screenshot".

Som sagt har jeg haft visse vanskeligheder med at få dette til at fungere, men ikke desto mindre, er det utrolig mange ressourcer der bliver brugt og da tid er en vigtig faktor, håber jeg meget at der findes en bedre metode som jeg ikke har regnet ud endnu.



Jeg mente nu ikke at du skulle løbe alle pixels igennem, 3-4 pixels ville være nok fordelt inden for eks 32 x 32 pixels.

Problemet er så at det kan være et hvilket som helst sted på din skærm. Dertil dur min metode ikke, det er mere hvis den kun kan være eet sted, og så enten være der eler ej.

Jeg kan ikke umiddelbart se en nem løsning på dit problem



I virkeligheden ville det smarte vel være at konvertere både screenshot og pattern til et bitset eller lignende, derefter vil det være let at foretage testen.

Fold kodeboks ind/udKode 


Dette overskrider i midlertid mine evner.



Indlæg senest redigeret d. 02.03.2011 19:07 af Bruger #4414
En lille opdatering. Jeg er blevet informeret om at "brute force" metode er den hurtigste i mit tilfælde, så nu er der faktisk kun tilbage at finde ud af kode strukturen som jeg stadig slås med.



Umiddelbart vil jeg da tro at Brian's ide i det mindste vil virke til rimelig hurtigt at bort kaste forkerte resultater:

Vælg x forskellige pixels i dit mønster og sørg for at de ikke er for ens. Fuldkomman random pick virker sikkert fint:

Fold kodeboks ind/udKode 


Og så det bare at løbe skærmbilledet igennem
Fold kodeboks ind/udKode 


Noget i den retning.



Hvis dit billede eksempelvis er 32 x 32 pixels, så kan du jo se på dit mønster, lave en lige linie igennem det på tværs. Så har du 32 x 1 pixel. Så kan du løbe alle "linie" igennem i dit billede og se om din sekvens er i den linie... ved ikke hvad træfsikkerheden er, måske > 90%



Mit pattern er i den størrelsesorden, men billedet jeg skal finde omtalte pattern i kan være op til 1920*1200, muligvis større.

Kun at søge efter en linje fra mit pattern er naturligvis en mulighed, ligesom det er en mulighed kun at søge efter en pixel, men for at sikre at den rigtige position bliver funder, ønsker jeg at søge på det fulde pattern.



Faldt lige over dit problem, og så at ingen havde postet kode :)

Følgende virker fint, men er fuldstændigt uoptimeret. Denne metode matcher et helt bitmap, så du skal selvfølgelig kun matche på pixels, hvor din patterns har alpha!=0.

Fold kodeboks ind/udKode 




Indlæg senest redigeret d. 11.03.2011 15:50 af Bruger #16471
t