slacky Skrevet 20. mai 2012 Del Skrevet 20. mai 2012 (endret) Hei. Jeg leter etter alternativ løsning for å finne fargen til en gitt piksel på skjermen. Grunnlag: Jeg finner Java.awt.Robot sin "getPixelColor" sinnsykt treg. Tidligere, i python så har jeg tatt printscreen av skjermen, for å så søke i bildet etter en bestemt farge, og returnere pikselen hvor den ble funnet. Indentation er nok bare "diskusjon.no" som tuller. Java-søkeversjonen: public static int[] colorAt(int x, int y) throws Exception { Robot r = new Robot(); Color c = r.getPixelColor(x, y); int[] color = {c.getRed(), c.getGreen(), c.getBlue()}; return color; } public static Point colorFindSpiral(int[] rgb, int X, int Y, int W, int H) throws Exception { int x=0, y=0, dx=0, dy=-1; int t = Math.max(X,Y); int maxI = t*t; int old = (int) (System.currentTimeMillis()); for (int i=0; i < maxI; i++){ if ((-X/2 < x && x <= X/2) && (-Y/2 < y && y <= Y/2)) { int[] color = colorAt(x+W,y+H); if(color[0]==rgb[0] && color[1]==rgb[1] && color[2]==rgb[2]) { return new Point(x+W,y+H); } } if((x == y) || ((x < 0) && (x == -y)) || ((x < 0) && (x == 1-y))){ t=dx; dx=-dy; dy=t; } x+=dx; y+=dy; } System.out.println((int) (System.currentTimeMillis())-old); return null; } Python-variant (nesten tilsvarande) som er flere ti-talls hakk raksere, hvor jeg tar printscreen, for å så søke i bildet: def FindSpiral(hex, X, Y, W, H, tol): image = ImageGrab.grab() #Printscreen r,g,b = hex_to_rgb(hex) lab = rgb_to_lab(r, g, b) sx,sy,dx,dy = 0,0,0,-1 WX,HY = (W+X)/2, (H+Y)/2 pix = image.load() for i in xrange(max((W-X), (H-Y))**2): if (-WX < sx <= WX) and (-HY < sy <= HY): px = pix[WX+sx, HY+sy] px = rgb_to_lab(px[0],px[1],px[2]) if max(map(lambda a,b: abs(a-b), px, lab)) < tol: return WX+sx, HY+sy if sx == sy or (sx < 0 and sx == -sy) or (sx < 0 and sx == 1-sy): dx, dy = -dy, dx sx, sy = sx+dx, sy+dy Noen tips til raskere fremgangsmåte? Endret 22. mai 2012 av warpie Lenke til kommentar
HV Skrevet 21. mai 2012 Del Skrevet 21. mai 2012 java.awt.Color har vell ingen metode kalt "colorAt"? Siden eksemplet ditt da ikke kompilerer så vet jeg ikke hva som går tregt hos deg, og du har jo heller ingen benchmarks å måle opp med. Min metode bruker da under 30ms på et bilde som er 1000px*1000px 0ms hvis koden finner farge på første pixel og ca 28ms hvis bilder ikke inneholder fargen i det hele tatt, Jeg skjønner ikke helt hvorfor du sender in x,y,w,h til metoden din, men hvis intensjonen er å kun søke gjennom et rektangel i bilden så kan mitt forslag oppdaters ved å benytte variabler i for løkkene til å minimere søket og da vil selfølgelig søket gå enda raskere.. import java.awt.Color; import java.awt.Point; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import org.junit.Test; public class ColorTest { @Test public void testColorSearch() throws IOException { final BufferedImage read = ImageIO.read(new File("D:\\Images\\red.png")); final BufferedImage image = new BufferedImage(read.getWidth(), read.getHeight(), BufferedImage.TYPE_INT_ARGB); image.getGraphics().drawImage(read, 0, 0, null); final long start = System.currentTimeMillis(); final Point p = searchColor(image, new Color(255, 0, 0).getRGB()); final long end = System.currentTimeMillis(); if (p != null) { System.out.println("Found color at x=" + p.x + ", y=" + p.y + "in " + (end - start) + "ms"); } else { System.out.println("Didnt find color in " + (end - start) + "ms"); } } private static Point searchColor(final BufferedImage image, final int color) { final int[] pixels = ((DataBufferInt) (image).getRaster().getDataBuffer()).getData(); for (int x = 0; x < image.getWidth(); x++) { for (int y = 0; y < image.getHeight(); y++) { final int i = y * image.getWidth() + x; if (pixels[i] == color) { return new Point(x, y); } } } return null; } } Lenke til kommentar
slacky Skrevet 22. mai 2012 Forfatter Del Skrevet 22. mai 2012 (endret) Hmm... Ser nå at jeg har surret, men er rettet nå. PS: ~2 sekunder over 400*400, vs python som brukte millisekunder. Selve funksjonen er ikke verd å tenke på. Den er noe spesiell. Jeg passerer X,Y = størrelsen på delen av bilde/skjerm som loopes. W, H er hvilke punkter han skal starte søket. Selve funkjsonen er nermere beskrevet der: http://www.diskusjon...owtopic=1412156 Skal se over koden du viser til i løpet av ettermiddagen i morgen, og sansynligvis så har du løst mitt problem. //Edit ser nå at problemet var at jeg tok et nytt printscreen for hver del av loopen. Ved lage en løsning som benytter seg av BufferedImage så var dette løst. Endret 22. mai 2012 av warpie Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå