Results 1 to 11 of 11

Thread: (SCAR) Trouble finding bitmaps

  1. #1
    Join Date
    Oct 2009
    Posts
    4
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default (SCAR) Trouble finding bitmaps

    I'm having trouble finding bitmaps on the screen. I'm getting confusing results when I try to run a program to test the FindBitmap procedure (along with similar ones, like FindBitmapToleranceIn).

    Here's what I have so far. It's for a sort of card matching game, where you're given a bunch of face down cards and you have to try to match them by flipping two over at a time, and I'm trying to make a script that will play this automatically. This is not the final product though; The following code is just a way to test some functions in SCAR and see if they can do what I need them to do.

    The concerned area of the client currently looks like this:
    http://img33.imageshack.us/img33/6581/pic1ys.jpg

    Here's my code.
    Code:
    program New;
    
    Var
     BitmapArray:array[1..2] of integer;
     PosX:integer;
     PosY:integer;
     VarAc:Extended;
      
    Const
     BeginX=305;
     BeginY=80;
     EndX=800;
     EndY=580;
    
    begin
     BitmapArray[1] := Bitmapfromstring2(False, '');
     Copyclienttobitmap(BitmapArray[1], 320, 510, 355, 555);
     writeln(FindBitmap(BitmapArray[1], PosX, PosY));
     Clickmouse(400, 540, True);
     Wait(3000);
     Clickmouse(580,530,True);
     Wait(2000);
     writeln(FindBitmap(BitmapArray[1], PosX, PosY));
     writeln(FindBitmapToleranceIn(BitmapArray[1], PosX, PosY, BeginX, BeginY, EndX, EndY, 300));
     writeln(inttostr(PosX) + ' ' + inttostr(PosY));
     writeln(FindBitmapToleranceIn(BitmapArray[1], PosX, PosY, BeginX, BeginY, EndX, EndY, 275));
     writeln(inttostr(PosX) + ' ' + inttostr(PosY));
     writeln(FindBitmapToleranceIn(BitmapArray[1], PosX, PosY, BeginX, BeginY, EndX, EndY, 250));
     writeln(inttostr(PosX) + ' ' + inttostr(PosY));
     // writeln(FindDeformedBitmapToleranceIn(BitmapArray[1], PosX, PosY, BeginX, BeginY, EndX, EndY, 150, 1, True, VarAc));
    End
    Output:
    Code:
    Line 7: [Hint] (7:1): Variable 'VARAC' never used in script 
    1
    320 510
    0
    1
    321 99
    1
    565 191
    0
    565 191
    Successfully executed
    Just to run through it step by step. First, it uses CopyClientToBitmap to save the image located at 320, 510, 355, 555 (In other words, a tiny portion of the bottomleftmost card). Then, (Just to test to see if it works), it searches for the same card in the entire client and prints the result (Which is 1, or True) and the coordinates (Which appears to be the correct position of the bottom left card).

    Then, it clicks on an adjacent card (Which I know is not a correct match), waits for it to reset the flipped cards, then clicks on a new card (Which I know should be the correct match). The screen now looks like this:
    http://img195.imageshack.us/img195/8608/pic4lh.jpg

    Then it searches for the previously saved image in the entire client again and prints the result. Here's the problem though; It keeps returning 0 (False), so it's obviously not finding it.

    It searches for the saved image in the client again, and prints the result, only using FindBitmapToleranceIn this time. It returns True, and then prints the coordinates. (Which appear to be incorrect; it is 'finding' the image far too high on the screen, and too far to the left.)

    It searches using FindBitmapToleranceIn again, with a slightly lower tolerance. It returns True, and prints coordinates. (Which also appear to be incorrect. I believe the value for the X axis is the correct position, but the value for the Y axis is far too high on the screen, meaning it is picking a face down card that is in the same column but a higher row.)

    And then search one more time using FindBitmapToleranceIn, with lower tolerance. This time it returns false. (I tell it to print the coordinates again, but since it did not find the image, the displayed coordinates have not changed from the last search.)

    The last one is a comment because I do not know if it is working properly. That function seems to take an excessively long time to complete (Although it does complete *eventually*).

    It seems that such a high tolerance makes it find the wrong image, even though a slightly lower once makes it not find a match at all. (I can bet, normally, tolerance would be set to something much lower? Maybe around 20-30?)

    Any idea why I would be getting such confusing results? I do have a theory of my own; I think, perhaps, that the source file that this applet is using it much bigger, so it is being scaled down for each instance of the card in the game. It could be that the resulting scaled image will be slightly different depending on where it is on the screen. (If this makes any sense to anybody)

    I want to note that once I close this game window, the next time I want to play around with this program I will have to restart it with a fresh game; the positions of the cards will be randomized.

  2. #2
    Join Date
    Oct 2009
    Posts
    4
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    So, no ideas? Nobody knows what could possibly be wrong?

    I'm gonna throw a few ideas out here, somebody tell me if they're sound.

    Maybe, instead of trying to compare the saved bitmap right to the card on the screen, I should use CopyCanvas to save it (so both of them are stored in variables) and use BitmapToString to compare them that way. I made a weird discovery just recently; I tried to compare to exact images using:

    Code:
    If(Image1 = Image2)Then
    begin
      writeln('Yay!')
    end else
    begin
      writeln('Borked')
    end;
    And somehow, it borked. But then, I tried:

    Code:
    If(bitmaptostring(Image1) = bitmaptostring(Image2))Then
    begin
      writeln('Yay!')
    end else
    begin
      writeln('Borked')
    end;
    And it works. Really weird.

    I have a question though, is there a way to compare strings within a tolerance? If I REALLY needed to, I might be able to make my own procedure to do that (comparing each individual character I guess), but if I had some insight on exactly how SCAR generates strings from bitmaps then it would be a lot easier.

  3. #3
    Join Date
    Oct 2006
    Location
    Netherlands
    Posts
    3,285
    Mentioned
    105 Post(s)
    Quoted
    494 Post(s)

    Default

    I got the same question:
    ...is there a way to compare strings within a tolerance?...
    And for scruttlemut:
    Why don't you use TPA's? They are way easier and lighter.
    Last edited by masterBB; 10-28-2009 at 11:29 PM.

  4. #4
    Join Date
    May 2008
    Location
    Canada
    Posts
    665
    Mentioned
    0 Post(s)
    Quoted
    7 Post(s)

    Default

    Know what? I had a problem with bitmap detection before. It was a problem with copying from microsoft paint... it changes some pixes of colours in your image. Problem fixed by screenshot of image in paint(black out the cornors so image is in a box shape), paste directly into the Scar image to string tool, and select your section after a zoom in (you can only select in rectangles).

  5. #5
    Join Date
    Oct 2009
    Posts
    4
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by masterBB View Post
    I got the same question:


    And for scruttlemut:
    Why don't you use TPA's? They are way easier and lighter.
    Not sure what TPA's are. An array of some sort? The core of my script right now relies on a quite large 3 dimensional array, though, so would a TPA be able to do that?


    @mrpickle: The thing is, though, the image files I'm using to compare to the client were taken directly from the client using SCAR using SaveBitmap. Unless something is buggy with the way SCAR saves its images, I shouldn't be getting a problem.


    Which brings me to a new issue... I'm getting close to the completion of my script, but there's still a few nagging errors.

    I wrote a script that will save images from the client for later use, and then later a separate script will load those same images and try to find them on the client. However, some of the images are matching properly, while others aren't, but they're all being saved the same way so I don't know why some work and some fail. Here's an example:

    I run the first script. It turns over Card A at position (1,1), and Card B at position (1,2). Later on, I'll run the second script. When it finds Card A at (1,1), it will recognize it as a match. But then, when Card B is found at (1,2), it doesn't recognize it.

    Here is the code I'm using to fill out this database:
    Code:
    Procedure InitializeBitmaps;
    begin
         CanvasSave:= bitmapfromstring2(False,'');
         CanvasSaveSm:= bitmapfromstring2(False,'');
         InitializeSm:= bitmapfromstring2(False,'');
         // The below is to initialize the database of pictures that will be used to match.
         For a:= 0 to 117 do
         begin
              For b:= 1 to 6 do
              begin
                   for c:= 1 to 4 do
                   begin
                        If FileExists('C:\PictureDatabase\'+inttostr(a)+'('+inttostr(b)+','+inttostr(c)+').bmp') then
                        begin
                             freebitmap(InitializeSm);
                             InitializeSm:= Loadbitmap('C:\PictureDatabase\'+inttostr(a)+'('+inttostr(b)+','+inttostr(c)+').bmp');
                             EndFlag:=False;
                             repeat
                                   PictureDatabase[a][b][c]:=bitmaptostring(InitializeSm);
                                   If(bitmaptostring(Loadbitmap('C:\PictureDatabase\'+inttostr(a)+'('+inttostr(b)+','+inttostr(c)+').bmp'))=PictureDatabase[a][b][c])then
                                   begin
                                        EndFlag:=True;
                                   end else
                                   begin
                                        writeln('Error in Initialize');
                                   end;
                             Until(EndFlag=True);
                        end;
                   end;
              end;
         end;
    End;
    This runs each time I use the script. B and C refer to the coordinates on the 'grid' of cards (B being the X axis and C being the Y axis). A refers to a number I've associated with each individual card. (But not in relation to position on the play field, because that's what B and C is for). For example, PictureDatabase[1][2][3] might be a picture of a Cat at position (2,3). PictureDatabase[1][3][5] will be a picture of the same Cat, except at position (3,5). The reason I need to do this and not just store a single picture is because the images at different locations are slightly different at a pixel level, even though they're the same to the human eye (Different enough to make FindBitmap and similar functions fuck up, at least). CanvasSave, CanvasSaveSm, and InitializeSm are just placeholders to hold images until they're saved elsewhere.

    Whenever it finds a card/position combo it doesn't recognize, I have it save it to an output folder to be sorted manually later. However, I've been noticing a lot of duplicates are being saved. Maybe about 65% of the images that I find in the output folder after the script is run are repeats of images I should already have. I'm having a lot of trouble nailing down exactly where the problem is, though. The only thing I can think of is that it's in the initialization procedure, because I figure if the image taken directly from the client isn't recognized, it's more likely the image in my database that's at fault.

    However, I've run a few tests before. Using the easy comparison procedure I did in my last post:
    Code:
    If(bitmaptostring(Image1) = bitmaptostring(Image2))Then
    begin
      writeln('Yay!')
    end else
    begin
      writeln('Borked')
    end;
    I ran the recently saved picture as Image1 and the old picture that 'mismatched' as Image2, and it came up True. This suggests that maybe my code to compare images is wrong, but then it should fail with ALL of them, and not just some.

    And yes, the image database is really 2832 pictures big. That's what happens when there's 117 different cards and 24 different places to put each different card. I used macros to put most of it together, but it was still a pain in the ass. No, I'm not going to enter them all as constants, because I know while it would be more reliable then using the procedures above... I'm not doing 2832 lines of that by hand.

  6. #6
    Join Date
    Oct 2006
    Location
    Netherlands
    Posts
    3,285
    Mentioned
    105 Post(s)
    Quoted
    494 Post(s)

    Default

    A TPA is some sort of array of colours, it's much used for searching runescape etc. But if you would store some of the pixels(like 10 or 20) and there colours in this array, you can compare it with others. Also it is a lot smaller than taking a bitmap.

    And for your current solution to this problem... It can be done like 20 times as easy. What if you would just store a part of the middle of every card(not at all positions!) and would just search for it at those 24 locations. Maybe by using one of the find bitmap functions of scar.

  7. #7
    Join Date
    Oct 2009
    Posts
    4
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    I tried that already, masterBB, and it failed miserably. I explained that already.

    And these pictures are only 15x15 pixels anyways.

  8. #8
    Join Date
    Oct 2006
    Location
    Netherlands
    Posts
    3,285
    Mentioned
    105 Post(s)
    Quoted
    494 Post(s)

    Default

    Can you give a link to the game, so I can try it too?

  9. #9
    Join Date
    Mar 2007
    Posts
    4,810
    Mentioned
    3 Post(s)
    Quoted
    3 Post(s)

    Default

    ScuttleMutt: I receive the exact same problem, whilst using CopyClientToBitmap to find something via FindBitmap/ToleranceIn. I think that the image is somehow altered during the process, it usually finds it with 120 - 250 tolerance though :/
    Last edited by Naum; 11-01-2009 at 06:10 PM.

  10. #10
    Join Date
    Sep 2006
    Posts
    6,089
    Mentioned
    77 Post(s)
    Quoted
    43 Post(s)

    Default

    Try using BitmapFromString instead of BitmapFromString2. I tried it and it works for me:

    SCAR Code:
    program New;
    var
      bmp,
      x, y,
      w, h: Integer;
    begin
      bmp := BitmapFromString(50, 50, '');
      CopyClientToBitmap(bmp, 100, 100, 149, 149);
      GetClientDimensions(w, h);
      if FindBitmap(bmp, x, y) then
        WriteLn(Format('%d:%d', [x, y]));
      if FindBitmapIn(bmp, x, y, 0, 0, w - 1, h - 1) then
        WriteLn(Format('%d:%d', [x, y]));
      if FindBitmapToleranceIn(bmp, x, y, 0, 0, w - 1, h - 1, 50) then
        WriteLn(Format('%d:%d', [x, y]));
    end.

  11. #11
    Join Date
    Feb 2006
    Location
    Belgium
    Posts
    3,137
    Mentioned
    3 Post(s)
    Quoted
    5 Post(s)

    Default

    BitmapFromString2 is highly deprecated and shouldn't be used at all under any circumstance, without a bitmap string that was specifically made for it, it's completely useless...

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •