Jump to content


Limited text search within an image for a specific font


  • Please log in to reply
25 replies to this topic

#1 dutchMaster

dutchMaster
  • Guests

Posted 01 July 2012 - 03:14 AM

Hi all,

I'm new to AHK but I want to dive right in. I have a very limited area I would need to search and that area contains a specific non-system font. I tried GOCR but it didn't work very well. Is there anyway I can "teach" my script to read certain images for text? It would only be numeric values so if I could provide an individual image for 0-9 that the script would be able to use to match up on the image, I'm thinking that would work! Any advise to get me started on how to do this?

#2 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 01 July 2012 - 05:48 AM

The 'teaching' involves writing a script to search for images of the numbers.
The method is to have copies of the numbers as images and search for them until a match is found.

Step 1 questions:
Is this in a game?
can you get a screen capture of the target area?
Can you capture and save all 10 digits as BMP files?
Can you capture a few examples of the target area (with different digits) ?

Is the background near (and behind) the numbers stable, or does it change?
How many digits together?
How fast do the numbers change?
Can you provide all of the above answers?

step 2 would involve doing some static testing
in my experience it is easier to work on the script when you don't have to manage the target.
(that might be one reason why artists begin learning by using still-life as their subject)
A gui can be written in just afew lines of code to show your target. This makes testing imagesearch easier.

#3 dutchMaster

dutchMaster
  • Guests

Posted 01 July 2012 - 06:32 AM

Is this in a game? Yes, I want to log values for a game.
can you get a screen capture of the target area? Yes.
Can you capture and save all 10 digits as BMP files? Yes.
Can you capture a few examples of the target area (with different digits) ? Yes.

Is the background near (and behind) the numbers stable, or does it change? Both? The background changes but it could only be 1 of 11 different backgrounds if that helps.
How many digits together? Usually 7 - 9 digits.
How fast do the numbers change? The numbers would change every few minutes.

#4 dutchMaster

dutchMaster
  • Guests

Posted 01 July 2012 - 09:26 PM

Any more ideas on how I can actually start the process? Thank you btw for your interest :)

#5 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 02 July 2012 - 06:49 AM

Any more ideas on how I can actually start the process? Thank you btw for your interest

Here is a script to get you started thinking. De.gif used to be on main AHK page so I tend to use that image.

Hopefully your target area (haystack) is smaller than your full screen
Start off using the same image for both the filenames.
Play with the script to see how it works.
Then change the needle to one of the 'digit' images and see how the script performs.

I chose to use a hotkey to trigger the search because it is easier to understand.
Later you can use settimer with a label "find_image" to automate the system.

I suggest reading every word of the ImageSearch docs, every bit will be important to you project.
For example, if you comprehend the docs you can answer this first question:
If there were multiple (non-overlapping) copies of the search image, which would the command find?

It takes a little more thinking to answer this question:
If you need to find a copy besides the first, how would you do it?

haystack_name = DE.gif
needle_name = DE.gif

; german flag 

;  UrlDownloadToFile, http://www.autohotkey.com/docs/images/DE.gif, de.gif

; you can use a fixed location 

randx = 100
randy = 100

; or you can use a random location 

Random, picx , 20, 250
Random, picy , 20, 250

gui, margin, 0, 0 ; give a full range of position for the haystack

gui, add, picture, x%picx% y%picy% , %haystack_name%
gui, add, text, y+20 , press F1 to search
gui, add, text, , press F12 to reload script and give random location
gui, show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%, mygui


return

f1::
find_image:
tooltip,  ; turn it off or it may interfere with search
mousemove, 0, 0
;tooltip move the cursor here just to show it sowmwhere ...
sleep, 100

ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, %needle_name%
if ErrorLevel = 2
    MsgBox Could not conduct the search.
else if ErrorLevel = 1
    tooltip Image not found.
else
  {
    mousemove, FoundX, FoundY
    tooltip The icon was found at %FoundX%x%FoundY%.
  }
return


#singleinstance force

;#Persistent

; my debugging tools are below this line
+esc::
  exitapp
f11::listvars
f12::reload


#6 dutchMaster

dutchMaster
  • Guests

Posted 02 July 2012 - 11:28 PM

Thank you for the awesome help! I played around with the script and read the doc on ImageSearch but there is one part that I don't understand what it is doing:

find_image:
;tooltip,  ; turn it off or it may interfere with search
mousemove, 0, 0
;tooltip move the cursor here just to show it sowmwhere ...
sleep, 100

I deleted that whole section and didn't see a difference on how the script ran.

#7 dutchMaster

dutchMaster
  • Guests

Posted 02 July 2012 - 11:48 PM

Never mind, I see what it does now. Can you explain the : in find_image: though? I thought variables used = and := as basic operators? What does the : do?

#8 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 02 July 2012 - 11:58 PM

There are 5 lines
1. the purpose is stated before the script listing

3. moves the mouse cursor "out of the way"
4. I already adding the ; so this line has no point, I leave lines that might be usefu in the script.
5. I like to make sure the cursor is "out of the way" before searching, call it "cheap insurance"

2. leave this line disabled/removed, run the script & press F1,
when the image is found and you see the tooltip, press F1 again
I think you will understand grasshopper :wink:

Can you explain the : in find_image: though?


See #1 above

:?: Btw, can you answer the 2 questions I asked ?

#9 dutchMaster

dutchMaster
  • Guests

Posted 03 July 2012 - 12:13 AM

Ty, I see now :D

#1 - The script would only find the first image out of multiple matches as it searches from top to bottom.

#2 - Put the imagesearch inside of a loop and contain the search area to only span across the value I want to find?
So for example, if the entire area I wanted to search was 800 x 600 but the actual area of each number set is only 100x20, do an image search for each 100x20 area and make a loop to find all matches.

#10 dutchMaster

dutchMaster
  • Guests

Posted 03 July 2012 - 12:22 AM

Gah, I'm stumped again :(

I tried to replace the images with:

haystack: http://i45.tinypic.com/16iy8eo.jpg
needle: http://i49.tinypic.com/143pe2u.jpg

I'm guessing it isn't working because the 1 digit is not at the top left corner of the haystack image?

#11 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 03 July 2012 - 12:44 AM

I'm guessing it isn't working because the 1 digit is not at the top left corner of the haystack image?

No, that is not the problem.
The purpose of the search is to find the image wherever it is, as long as it is in the field of view.

The actual problem is related to the file image format you are using, JPG. Jpg format compresses the image size, but some pixel information is lost.

I specified using BMP in my first reply. Please go back and capture the images and save using BMP file format.

Btw, must the needle be that tall ?

#12 dutchMaster

dutchMaster
  • Members
  • 8 posts

Posted 03 July 2012 - 01:15 AM

No, I changed it to be that tall because I thought it might need to be the same height.

Worked perfectly when changed to .bmp :) also changed needle image to only be width/height of the digit.

#13 dutchMaster

dutchMaster
  • Members
  • 8 posts

Posted 03 July 2012 - 02:02 AM

Here's where I'm at now:

;
; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         A.N.Other <myemail@nowhere.com>
;
; Script Function:
;	Template script (you can customize this template by editing "ShellNew\Template.ahk" in your Windows folder)
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

haystack_name = sm.bmp
dig1 = n1.bmp
digcom = comma.bmp
dig0 = 0.bmp
dig5 = 5.bmp

; you can use a fixed location

randx = 100
randy = 100

; or you can use a random location

;Random, picx , 20, 250
;Random, picy , 20, 250

gui, margin, 0, 0 ; give a full range of position for the haystack

gui, add, picture, x%randx% y%randy% , %haystack_name%
gui, add, text, y+20 , press F1 to search
gui, add, text, , press F12 to reload script and give random location
gui, show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%, GameImageSearch


return

f1::
find_image:
tooltip,  ; turn it off or it may interfere with search
mousemove, 0, 0
;tooltip move the cursor here just to show it sowmwhere ...
sleep, 100

is1 = ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, %dig1%
is2 = ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, %digcom%
is3 = ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, %dig0%
is4 = ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, %dig5%

if ErrorLevel = 2
    MsgBox Could not conduct the search.
else if ErrorLevel = 1
    tooltip Image not found.
else
  {
    mousemove, FoundX, FoundY
    tooltip The icon was found at %FoundX%x%FoundY%.
    Run, notepad datalog.txt
    IfWinExist, datalog - Notepad
	WinActivate
	if (is1 ErrorLevel) {
	Send, 1
	} if (is2 ErrorLevel) {
	Send, ,
	} if (is3 ErrorLevel) {
	Send, 0
	} if (is4 ErrorLevel) {
	Send, 5
	}
    else
	WinActivate, GameImageSearch
  }
return


#singleinstance force

;#Persistent

; my debugging tools are below this line
+esc::
  exitapp
f11::listvars
f12::reload

The issues I'm having:
Script won't log values the first time I press f1. If I press it a second time, it does.
It is running the imagesearch's in subsequent value, which is not good! It needs to be dynamic, search the area more than once until it doesn't find any more.

One thing that is killing me as I think ahead is how do I keep the integrity of the number locations? So if my starting number is 1,500,000, how do I get it to log it from left to right.

Basically I am envisioning a slot machine column spinning really fast until it finds a match. Then stops and goes to the next column. But how do I define the columns!!

#14 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 03 July 2012 - 05:44 AM

Your stacking of several imageseach commands will not work.

I suggest reading every word of the ImageSearch docs, every bit will be important to you[r] project.


first and foremost, imagesearch is a command not a function.
Please search in the helpfile for the word 'functions' and then read "Introduction and Simple Examples"

I see that you left my hotkeys in your script; good.
Please notice of you run the script and press F11 you will get a list of variables and their values
for example haystack_name[6 of 7]: sm.bmp the variable 'haystack_name' is holding 6 characters and currently has room for 7 total.
the variable contents are a string of characters "sm.bmp" w/o the ""

Now close the running script and edit the script file.
msgbox this a test ; <---- please add this line of code 
if ErrorLevel = 2

save and run the script again, hit F1 and wait for the magbox and then hit F11 again.
look at the values for is1 is2 ....

Is this a good time to ask if you have worked through the tutorial ?
<!-- m -->http://www.autohotke...cs/Tutorial.htm<!-- m --> :oops:


I see what you are saying about logging left to right, and I can't immediately speak to that.
I have only one example from you on what the target looks like.
Can you describe or post varying examples of the target ?
Are the digits always aligned in columns, or would 1,111,000 actual be less wide because the '1' are more narrow than the '0' ?

If we go ahead with the assumption that the digits all occupy same width,
then I see the slot machine idea has some merit.

If we assume 7 columns of digits (ignoring the commas) and worse case, we would have to search for 10 digits in each column. That means 70 searches per result.
"Worse case" means that no matter what order we choose to search for the digits, we are always wrong.
The best case would be if all the digits were our first choice, and would take 7 searches.

I have another idea that will reduce the max and increase the min so that the number of searches is fixed at 17.

#15 dutchMaster

dutchMaster
  • Members
  • 8 posts

Posted 03 July 2012 - 07:29 PM

I haven't read every bit of the tutorial but I have read sections! :oops:

I just found this thread:
<!-- l --><a class="postlink-local" href="http://www.autohotkey.com/community/viewtopic.php?f=15&t=87293">viewtopic.php?f=15&t=87293</a><!-- l -->
It's the same game / scenario that I want to do.

I did try the OCR again because the last poster in that thread said it was working for him, but I still can't get it to work.

The digit images will be variable widths so yeah, guess the slot machine idea is toast.