SRL Archive - Help and Support

Need help reading text.


bud_wis_er_420

2013-12-27 23:05:23

Ok I'm making a bot for a game called Eve Online. I need to be able to read text to get the cargo name, quantity, etc. I remade all the fonts. Everything was working well till I hit a snag. In this word..

.. the "ct" are touching. Instead of reading "Insecticide", my results are "InseYicide".I have to stick with the color and color tol I have. Which is color: 10329501 and tol: 117; I spent hours with aca to get that color just right. Btw I tryied removing the grey part of the outer edges of c didn't work. You can see what the script sees as text with this pic.

I thought with a min spacing of 0 it would pick up that those are 2 different characters.

Here are the characters in question.

Can I not get Simba to read touching characters?

Below you can download everything I got to see for your self. The bot works, it just hangs up on this word and only this word so far. It reads everything else just fine. I tried every which way I could think of to edit the pics to make it work. With black edges, no black edges, only black edges on the side of the chars that are not touching.


My get text function…

function GetTextIn(x1, y1, x2, y2: integer): string;
var
TPA: TPointArray;
Box: TBox;
begin
Result := 'Failed to get Text';
Box := IntToBox(x1, y1, x2, y2);
if FindColorsTolerance(TPA, 10329501 , Box.X1, Box.Y1, Box.X2, Box.Y2, 117) then
begin
Box := GetTPABounds(TPA);
//writeln(ToStr(Box));
Result := GetTextAtExWrap(Box.X1, Box.Y1 - 3, Box.X2, Box.Y2, 0, 3, 3, 10329501 , 117, 'EveNormalText');
end;
end;

A screenshot of the client you can test with.
http://img9.imageshack.us/img9/8839/ry67.png

Thanks for any help you can give guys.

Justin

2013-12-28 00:05:34

We have (had?) the same problem with SRL6 with 'rt' as it reads 'n'. I don't think there is a way, maybe @Olly; can help?

Olly

2013-12-28 00:42:01

Quick answer is no. You can not get simba to read merged chars.

But.. :p



{$i srl-6/srl.simba}

var
bmp := BitmapFromString(454, 105, 'meJzt3L+uplMUx/HxZzQ0EpmIxAyCTkI7CQqEhNodqLgGV6ATlcKQYWIyNBJMFG5Nq/ntZCV7P89eTz6fC1jvPmvv91udc27cAAAAAAAA4FA3g7PPBdCPogLMoqgAsygqwCyKCjCLogLMoqgAsyhq1Z/B2efimr4NZs1/HDwTzPrcWXY7/2/B6s/tS1E5kqKO7XZ+Ra1SVI6kqGO7nV9RqxSVIynq2G7nV9QqReVIijq22/kVtUpROZKiju12fkWtUlSOpKhju51fUasUlSMp6thu51fUKkXlSN5bL38EZ59rX144R/LeelHUKi+cI3lvvShqlRfOkby3XhS1ygvnSN5bL4pa5YVzJO+tF0Wt8sI5kvfWi6JWeeEcyXvrRVGrqi/8ueBB8EvwMPggqP5cHwfpc+8F7wfV87wbpL2lc34aVM9zN0j3dT/4Mvgi+DdI878O0s81q9ir97P6/J8Ej4L0lxezzrPb+19HURVVUY/fz+rzK+pZFFVRFfX4/aw+v6KeRVEVVVGP38/q8yvqWRRVURX1+P2sPr+inkVRFVVRj9/P6vMr6lkUVVEV9fj9rD6/op5FURVVUY/fz+rzK+pZqht7IvgneCO4HaRNVn+u9J9yXw5eCN4OqudJ38Q7wa3g96B6nvSSXw/Svb8YpM+d9Q1dPb/7flI5XwnSO/w7qJ5nt/e/jqIqasdirJ7ffT+KehZFVdSOxVg9v/t+FPUsiqqoHYuxen73/SjqWRRVUTsWY/X87vtR1LMoqqJ2LMbq+d33o6hnUVRF7ViM1fO770dRz6KoitqxGKvnd9+Pop5l1g3OmjPrP9x+H6TffH46qH5u8lfwVJBe/qwXtbpsZ33ubu/5rM+dNWfW93G397/OVW9QUce6F2P1/O77mTVHUauueoOKOta9GKvnd9/PrDmKWnXVG1TUse7FWD2/+35mzVHUqqveoKKOdS/G6vnd9zNrjqJWXfUGFXWsezFWz+++n1lzFLXqqjeoqGPdi7F6fvf9zJqjqFVXvUFFHetejNXzu+9n1hxFrbrqDb4ZfBOkvwj4MKie53HwQ/BjMOs83Yuxen73/cyaM+v7uNv7X+eqN6ioY92LsXp+9/3MmqOoVVe9QUUd616M1fO772fWHEWtuuoNKupY92Ksnt99P7PmKGrVVW9QUce6F2P1/O77mTVHUauueoOKOta9GKvnd9/PrDmKWnXVG1TUse7FWD2/+35mzVHUqqveoKKOdS/G6vnd9zNrjqJWXfUGq94Kfgqq89NvOKf/VLziZ/y/7sVYPb/7fmbNmfV93O39r3PVG6xS1F7FWD2/+35mzVHUqqveYJWi9irG6vnd9zNrjqJWXfUGqxS1VzFWz+++n1lzFLXqqjdYpai9irF6fvf9zJqjqFVXvcEqRe1VjNXzu+9n1hxFrbrqDVYpaq9irJ7ffT+z5ihq1VVvsEpRexVj9fzu+5k1R1GrrnqDnwfPB7eDh0H1PL8G7wQ3g3TO6nnSz/VqkF7+S0H63PSXFK8FTxbNeodn7WfW+R8F6fx3gvSb+dXz7Pb+11FURVXUffajqIo6d46iKqqiKqqiKurYbi9KUffcj6Iq6tw5iqqoiqqoiqqoY7u9KEXdcz+Kqqhz5yiqoiqqoiqqoo7t9qIUdc/9KKqizp0zq6gfBPeC9A1Kc6rnuRs8CO4HnwXV87wXpPP8HHwVVO8llTb95+Fbwax3eNZ+Zp3/oyC987Tn74Jng3Se3d7/OoqqqIq6z34UVVHnzlFURVVURVVURR3b7UUp6p77UVRFnTtHURVVURVVURV1bLcXpah77kdRFXXuHEVVVEVVVEVV1LHdXpSi7rkfRe1eVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjhP0tJ8Tk=');

begin
setTargetBitmap(bmp);
thresholdAdaptiveBitmap(bmp, 0, 255, false, TM_MinMax, 10);
debugBitmap(bmp);
freeTarget(getImageTarget());
freeBitmap(bmp);
end.

bg5

2013-12-28 02:00:41

or you can just search for InseYicide in script :)

bud_wis_er_420

2013-12-28 13:56:46

From: Olly
Quick answer is no. You can not get simba to read merged chars.

But.. :p



{$i srl-6/srl.simba}

var
bmp := BitmapFromString(454, 105, 'meJzt3L+uplMUx/HxZzQ0EpmIxAyCTkI7CQqEhNodqLgGV6ATlcKQYWIyNBJMFG5Nq/ntZCV7P89eTz6fC1jvPmvv91udc27cAAAAAAAA4FA3g7PPBdCPogLMoqgAsygqwCyKCjCLogLMoqgAsyhq1Z/B2efimr4NZs1/HDwTzPrcWXY7/2/B6s/tS1E5kqKO7XZ+Ra1SVI6kqGO7nV9RqxSVIynq2G7nV9QqReVIijq22/kVtUpROZKiju12fkWtUlSOpKhju51fUasUlSMp6thu51fUKkXlSN5bL38EZ59rX144R/LeelHUKi+cI3lvvShqlRfOkby3XhS1ygvnSN5bL4pa5YVzJO+tF0Wt8sI5kvfWi6JWeeEcyXvrRVGrqi/8ueBB8EvwMPggqP5cHwfpc+8F7wfV87wbpL2lc34aVM9zN0j3dT/4Mvgi+DdI878O0s81q9ir97P6/J8Ej4L0lxezzrPb+19HURVVUY/fz+rzK+pZFFVRFfX4/aw+v6KeRVEVVVGP38/q8yvqWRRVURX1+P2sPr+inkVRFVVRj9/P6vMr6lkUVVEV9fj9rD6/op5FURVVUY/fz+rzK+pZqht7IvgneCO4HaRNVn+u9J9yXw5eCN4OqudJ38Q7wa3g96B6nvSSXw/Svb8YpM+d9Q1dPb/7flI5XwnSO/w7qJ5nt/e/jqIqasdirJ7ffT+KehZFVdSOxVg9v/t+FPUsiqqoHYuxen73/SjqWRRVUTsWY/X87vtR1LMoqqJ2LMbq+d33o6hnUVRF7ViM1fO770dRz6KoitqxGKvnd9+Pop5l1g3OmjPrP9x+H6TffH46qH5u8lfwVJBe/qwXtbpsZ33ubu/5rM+dNWfW93G397/OVW9QUce6F2P1/O77mTVHUauueoOKOta9GKvnd9/PrDmKWnXVG1TUse7FWD2/+35mzVHUqqveoKKOdS/G6vnd9zNrjqJWXfUGFXWsezFWz+++n1lzFLXqqjeoqGPdi7F6fvf9zJqjqFVXvUFFHetejNXzu+9n1hxFrbrqDb4ZfBOkvwj4MKie53HwQ/BjMOs83Yuxen73/cyaM+v7uNv7X+eqN6ioY92LsXp+9/3MmqOoVVe9QUUd616M1fO772fWHEWtuuoNKupY92Ksnt99P7PmKGrVVW9QUce6F2P1/O77mTVHUauueoOKOta9GKvnd9/PrDmKWnXVG1TUse7FWD2/+35mzVHUqqveoKKOdS/G6vnd9zNrjqJWXfUGq94Kfgqq89NvOKf/VLziZ/y/7sVYPb/7fmbNmfV93O39r3PVG6xS1F7FWD2/+35mzVHUqqveYJWi9irG6vnd9zNrjqJWXfUGqxS1VzFWz+++n1lzFLXqqjdYpai9irF6fvf9zJqjqFVXvcEqRe1VjNXzu+9n1hxFrbrqDVYpaq9irJ7ffT+z5ihq1VVvsEpRexVj9fzu+5k1R1GrrnqDnwfPB7eDh0H1PL8G7wQ3g3TO6nnSz/VqkF7+S0H63PSXFK8FTxbNeodn7WfW+R8F6fx3gvSb+dXz7Pb+11FURVXUffajqIo6d46iKqqiKqqiKurYbi9KUffcj6Iq6tw5iqqoiqqoiqqoY7u9KEXdcz+Kqqhz5yiqoiqqoiqqoo7t9qIUdc/9KKqizp0zq6gfBPeC9A1Kc6rnuRs8CO4HnwXV87wXpPP8HHwVVO8llTb95+Fbwax3eNZ+Zp3/oyC987Tn74Jng3Se3d7/OoqqqIq6z34UVVHnzlFURVVURVVURR3b7UUp6p77UVRFnTtHURVVURVVURV1bLcXpah77kdRFXXuHEVVVEVVVEVV1LHdXpSi7rkfRe1eVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjhP0tJ8Tk=');

begin
setTargetBitmap(bmp);
thresholdAdaptiveBitmap(bmp, 0, 255, false, TM_MinMax, 10);
debugBitmap(bmp);
freeTarget(getImageTarget());
freeBitmap(bmp);
end.


Nope won't work. As I said, can't change color. As you can see, by just selecting the only 2 colors that make up the comma is also the same two colors that make the c and t join. That's what I ment when I said I tried removing the outer grey part of the letter "c".



From: bg5
or you can just search for InseYicide in script :)


I need the Text, to use later, to enter in a search field to search for the item within my inventory. I guess I could make it where it it finds this particular word it will change it to the correct one. But What if it happens again on another word I haven't ran across yet. I was looking for a more permanent fix.

A few things come to mind. One is to break down the whole text and search for only pieces of it till it finds 1 item in inv box. Instead of entering…

"Creates of InseYicide"

It will try different combinations till it finds only one item remaining in inv.
"Create"
"eates of I"
"es of InseY"
" of InseYici"
"Creates of "
"ates of Inse"

This is a last resort though. As it will take up time I don't want to use looking for the right text to use, when it only happens every once and awhile.

What I'd like to do, is try to fix the text reading function to work for me instead. So my next question is where do I find the source code for functions within simba? I want to look at it and see if I can edit it to work for me.

If not, my next choice I think I will try is just removing the comma from the fonts altogether. I don't think I will ever need it. This way I can change the color and the c and t will no longer join.

Olly

2013-12-28 14:26:26

Huh, why won't thresholding work? the text is perfectly there in red..?

bg5

2013-12-28 17:25:35

If you have only problem with ct being read as Y ,you can make hotfix and put it after OCR function.


function FixOcrDF ( text : string) : string;

begin
if not( ( Pos('Y',item_name) = 1 )or( Pos(' Y',item_name) <> 0 ) ) then //check if Y is not first letter of the word
text := Replace(text,'Y','ct');

end;


I have script for one game in which I had similar (even worse because of smalleer font) problem with OCR and couldn't fix it. I made about 20 hot fixes like that and it works perfectly.

Ashaman88

2013-12-29 00:35:39

I believe Olly is saying to use the new tesseract stuff

bud_wis_er_420

2013-12-31 16:00:03

From: Ashaman88
I believe Olly is saying to use the new tesseract stuff



new tesseract stuff?

Oh, I see, a new text reading method by Olly. I will look into it thx.

Olly

2013-12-31 16:51:01

No, I was saying adding a simple threshold to the image will get you a perfect set of chars to read.

Dgby714

2013-12-31 20:51:31

From: bud_wis_er_420
new tesseract stuff?

Oh, I see, a new text reading method by Olly. I will look into it thx.


No.. Tesseract was written by Ray Smith.

From: Olly
No, I was saying adding a simple threshold to the image will get you a perfect set of chars to read.


Do this^

bud_wis_er_420

2014-01-01 17:25:12

From: Dgby714
No.. Tesseract was written by Ray Smith.


I found this source code for the Tessa-what-ever at this page. And it had "By Olly" written all over it so I figured Olly wrote it. My mistake.
{$loadlib libtesseract}

var
savePath, imgPath: string;

const {resize multipler w, resize multipler h, invert? threshold amount}
FILTER_SMALL_CHARS: array [0..3] of variant = [3, 3, false, 50];
FILTER_NPC_CHAT_CHARS: array [0..3] of variant = [3, 3, true, -50];
FILTER_SMALL_CHARS_2: array [0..3] of variant = [5, 5, false, 55];

{*
__initTesseractPaths
~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

procedure __initTesseractPaths();

Loads the paths needed for tesseract to function.

.. note::

- By: Olly
- Last Updated: December 13, 2013 by Olly

Example:

.. code-block:: pascal

__initTesseractPaths();
*}
procedure __initTesseractPaths();

function bracketReplace(s: string): string;
begin
result := replace(s, '\', '/', [rfReplaceAll]);
end;

const
basePath = includePath + 'srl-6/lib/tesseract/';
begin
savePath := bracketReplace(basePath + 'temp/tmp-'+toStr(client));
imgPath := bracketReplace(basePath + 'temp/img-'+toStr(client)+'.bmp');

tesseractSetPaths(bracketReplace(basePath + 'tesseract.exe'), imgPath, savePath);

addOnTerminate('__deleteTesseractFiles');
end;

{*
__deleteTesseractFiles
~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

procedure __deleteTesseractFiles();

Deletes files created by the tesseract.

.. note::

- By: Olly
- Last Updated: December 13, 2013 by Olly

Example:

.. code-block:: pascal

__deleteTesseractFiles();
*}
procedure __deleteTesseractFiles();
begin
if (fileExists(savePath + '.txt')) then
deleteFile(savePath + '.txt');

if (fileExists(imgPath)) then
deleteFile(imgPath);
end;

(*
tesseractGetText; overload
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function tesseractGetText(const bmp: integer; const config: string): string; overload;

Overloaded method, reads the text from a bitmap, rather than a file.

.. note::

- By: Olly
- Last Updated: December 13, 2013 by Olly

Example:

.. code-block:: pascal

writeln(tesseractGetText(bmp));
*)
function tesseractGetText(const bmp: integer; config: string = ''): string; overload;
begin
saveBitmap(bmp, imgPath);
result := tesseractGetText(config);
end;

(*
tesseractGetText; overload
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function tesseractGetText(const x1, y1, x2, y2, resizeMultipler: integer; threshInvert: boolean; threshAmount: integer; config: string = ''): string; overload;

Overloaded method, reads text in area x1, y1, x2, y2 on the client

- resizeMultiW - How much to enlarge the width of the image (2 = double etc..).
- resizeMultiH - How much to enlarge the height of the image (2 = double etc..).
- threshInvert - Invert the threshold? (if text background is brighter than text, invert should be true).
- threshAmount - Amount to add/subtract to the threshold.
- config - What chars to only extract (currently only supports 'digits') - defualt set as ''.

.. note::

- By: Olly
- Last Updated: December 22, 2013 by Olly

Example:

.. code-block:: pascal

writeln(tesseractGetText(woBoxes[i].x1, woBoxes[i].y1, woBoxes[i].x2, woBoxes[i].y2, 3, 3, 50, false));
*)
function tesseractGetText(const x1, y1, x2, y2, resizeMultiW, resizeMultiH: integer; threshInvert: boolean; threshAmount: integer; config: string = ''): string; overload;
var
matrix: T2DIntegerArray;
bmp, w, h, rw, rh: integer;
{$IFDEF TESSERACT_DEBUG} t: integer := getSystemTime(); {$ENDIF}
begin
bmp := bitmapFromClient(x1, y1, x2, y2);

try
getBitmapSize(bmp, w, h);

if (w > 1) and (h > 1) then
begin
matrix := bitmapToMatrix(bmp);

if (resizeMultiW > 0) and (resizeMultiH > 0) then
resizeBilinearMatrix(matrix, resizeMultiW * w, resizeMultiH * h);

thresholdAdaptiveMatrix(matrix, 0, 255, threshInvert, TM_Mean, threshAmount);
drawMatrixBitmap(bmp, matrix);

result := tesseractGetText(bmp, config);
end else
writeln(format('tesseractGetText(): Bitmap is is too small (%d, %d)', [w, h]));

{$IFDEF TESSERACT_DEBUG}
writeln(format('tesseractGetText(): Resized (%d > %d, %d > %d), took %d ms. output = " %s "', [w, length(matrix[0]), h, length(matrix), getSystemTime() - t, result]));
displayDebugImgWindow(length(matrix[0]), length(matrix));
drawBitmapDebugImg(bmp);
{$ENDIF}

finally
freeBitmap(bmp);
end;
end;

(*
tesseractGetText; overload
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function tesseractGetText(const x1, y1, x2, y2: integer; filterMethod: array [0..2] of variant; config: string = ''): string; overload;

Overloaded method, reads text in area x1, y1, x2, y2 on the client with a default filter.
Use one of the filter constants found at the top of this file.

.. note::

- By: Olly
- Last Updated: December 22, 2013 by Olly

Example:

.. code-block:: pascal

writeln(tesseractGetText(100, 100, 200, 200, FILTER_SMALL_CHARS));
*)
function tesseractGetText(const x1, y1, x2, y2: integer; filterMethod: array [0..3] of variant; config: string = ''): string; overload;
begin
result := tesseractGetText(x1, y1, x2, y2, filterMethod[0], filterMethod[1], filterMethod[2], filterMethod[3], config);
end;

begin
__initTesseractPaths();
end;

From: Olly
No, I was saying adding a simple threshold to the image will get you a perfect set of chars to read.


By "threshold" do you mean CTS2?

Dgby714

2014-01-01 17:37:12

From: bud_wis_er_420
I found this source code for the Tessa-what-ever at this page. And it had "By Olly" written all over it so I figured Olly wrote it. My mistake.
{$loadlib libtesseract}

var
savePath, imgPath: string;

const {resize multipler w, resize multipler h, invert? threshold amount}
FILTER_SMALL_CHARS: array [0..3] of variant = [3, 3, false, 50];
FILTER_NPC_CHAT_CHARS: array [0..3] of variant = [3, 3, true, -50];
FILTER_SMALL_CHARS_2: array [0..3] of variant = [5, 5, false, 55];

{*
__initTesseractPaths
~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

procedure __initTesseractPaths();

Loads the paths needed for tesseract to function.

.. note::

- By: Olly
- Last Updated: December 13, 2013 by Olly

Example:

.. code-block:: pascal

__initTesseractPaths();
*}
procedure __initTesseractPaths();

function bracketReplace(s: string): string;
begin
result := replace(s, '\', '/', [rfReplaceAll]);
end;

const
basePath = includePath + 'srl-6/lib/tesseract/';
begin
savePath := bracketReplace(basePath + 'temp/tmp-'+toStr(client));
imgPath := bracketReplace(basePath + 'temp/img-'+toStr(client)+'.bmp');

tesseractSetPaths(bracketReplace(basePath + 'tesseract.exe'), imgPath, savePath);

addOnTerminate('__deleteTesseractFiles');
end;

{*
__deleteTesseractFiles
~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

procedure __deleteTesseractFiles();

Deletes files created by the tesseract.

.. note::

- By: Olly
- Last Updated: December 13, 2013 by Olly

Example:

.. code-block:: pascal

__deleteTesseractFiles();
*}
procedure __deleteTesseractFiles();
begin
if (fileExists(savePath + '.txt')) then
deleteFile(savePath + '.txt');

if (fileExists(imgPath)) then
deleteFile(imgPath);
end;

(*
tesseractGetText; overload
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function tesseractGetText(const bmp: integer; const config: string): string; overload;

Overloaded method, reads the text from a bitmap, rather than a file.

.. note::

- By: Olly
- Last Updated: December 13, 2013 by Olly

Example:

.. code-block:: pascal

writeln(tesseractGetText(bmp));
*)
function tesseractGetText(const bmp: integer; config: string = ''): string; overload;
begin
saveBitmap(bmp, imgPath);
result := tesseractGetText(config);
end;

(*
tesseractGetText; overload
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function tesseractGetText(const x1, y1, x2, y2, resizeMultipler: integer; threshInvert: boolean; threshAmount: integer; config: string = ''): string; overload;

Overloaded method, reads text in area x1, y1, x2, y2 on the client

- resizeMultiW - How much to enlarge the width of the image (2 = double etc..).
- resizeMultiH - How much to enlarge the height of the image (2 = double etc..).
- threshInvert - Invert the threshold? (if text background is brighter than text, invert should be true).
- threshAmount - Amount to add/subtract to the threshold.
- config - What chars to only extract (currently only supports 'digits') - defualt set as ''.

.. note::

- By: Olly
- Last Updated: December 22, 2013 by Olly

Example:

.. code-block:: pascal

writeln(tesseractGetText(woBoxes[i].x1, woBoxes[i].y1, woBoxes[i].x2, woBoxes[i].y2, 3, 3, 50, false));
*)
function tesseractGetText(const x1, y1, x2, y2, resizeMultiW, resizeMultiH: integer; threshInvert: boolean; threshAmount: integer; config: string = ''): string; overload;
var
matrix: T2DIntegerArray;
bmp, w, h, rw, rh: integer;
{$IFDEF TESSERACT_DEBUG} t: integer := getSystemTime(); {$ENDIF}
begin
bmp := bitmapFromClient(x1, y1, x2, y2);

try
getBitmapSize(bmp, w, h);

if (w > 1) and (h > 1) then
begin
matrix := bitmapToMatrix(bmp);

if (resizeMultiW > 0) and (resizeMultiH > 0) then
resizeBilinearMatrix(matrix, resizeMultiW * w, resizeMultiH * h);

thresholdAdaptiveMatrix(matrix, 0, 255, threshInvert, TM_Mean, threshAmount);
drawMatrixBitmap(bmp, matrix);

result := tesseractGetText(bmp, config);
end else
writeln(format('tesseractGetText(): Bitmap is is too small (%d, %d)', [w, h]));

{$IFDEF TESSERACT_DEBUG}
writeln(format('tesseractGetText(): Resized (%d > %d, %d > %d), took %d ms. output = " %s "', [w, length(matrix[0]), h, length(matrix), getSystemTime() - t, result]));
displayDebugImgWindow(length(matrix[0]), length(matrix));
drawBitmapDebugImg(bmp);
{$ENDIF}

finally
freeBitmap(bmp);
end;
end;

(*
tesseractGetText; overload
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function tesseractGetText(const x1, y1, x2, y2: integer; filterMethod: array [0..2] of variant; config: string = ''): string; overload;

Overloaded method, reads text in area x1, y1, x2, y2 on the client with a default filter.
Use one of the filter constants found at the top of this file.

.. note::

- By: Olly
- Last Updated: December 22, 2013 by Olly

Example:

.. code-block:: pascal

writeln(tesseractGetText(100, 100, 200, 200, FILTER_SMALL_CHARS));
*)
function tesseractGetText(const x1, y1, x2, y2: integer; filterMethod: array [0..3] of variant; config: string = ''): string; overload;
begin
result := tesseractGetText(x1, y1, x2, y2, filterMethod[0], filterMethod[1], filterMethod[2], filterMethod[3], config);
end;

begin
__initTesseractPaths();
end;



By "threshold" do you mean CTS2?


That's just the include file, which prob was written by Olly, then there is the libtesseract plugin which I have no clue who wrote, then there is the actual tesseract plugin which was written mainly by Ray Smith. See here.

libtesseract is just boiler plate code to add tesseract methods to Simba, then Olly's include file makes a scripter-friendly interface. (hopefully)

slacky

2014-01-06 14:49:09

From: bud_wis_er_420
…
By "threshold" do you mean CTS2?


No he means using the threshold-function (nothing less, nothing more).
If the background is always darker then the text then just threshold it as he shows you:

{$i srl-6/srl.simba}

var
bmp := BitmapFromString(454, 105, 'meJzt3L+uplMUx/HxZzQ0EpmIxAyCTkI7CQqEhNodqLgGV6ATlcKQYWIyNBJMFG5Nq/ntZCV7P89eTz6fC1jvPmvv91udc27cAAAAAAAA4FA3g7PPBdCPogLMoqgAsygqwCyKCjCLogLMoqgAsyhq1Z/B2efimr4NZs1/HDwTzPrcWXY7/2/B6s/tS1E5kqKO7XZ+Ra1SVI6kqGO7nV9RqxSVIynq2G7nV9QqReVIijq22/kVtUpROZKiju12fkWtUlSOpKhju51fUasUlSMp6thu51fUKkXlSN5bL38EZ59rX144R/LeelHUKi+cI3lvvShqlRfOkby3XhS1ygvnSN5bL4pa5YVzJO+tF0Wt8sI5kvfWi6JWeeEcyXvrRVGrqi/8ueBB8EvwMPggqP5cHwfpc+8F7wfV87wbpL2lc34aVM9zN0j3dT/4Mvgi+DdI878O0s81q9ir97P6/J8Ej4L0lxezzrPb+19HURVVUY/fz+rzK+pZFFVRFfX4/aw+v6KeRVEVVVGP38/q8yvqWRRVURX1+P2sPr+inkVRFVVRj9/P6vMr6lkUVVEV9fj9rD6/op5FURVVUY/fz+rzK+pZqht7IvgneCO4HaRNVn+u9J9yXw5eCN4OqudJ38Q7wa3g96B6nvSSXw/Svb8YpM+d9Q1dPb/7flI5XwnSO/w7qJ5nt/e/jqIqasdirJ7ffT+KehZFVdSOxVg9v/t+FPUsiqqoHYuxen73/SjqWRRVUTsWY/X87vtR1LMoqqJ2LMbq+d33o6hnUVRF7ViM1fO770dRz6KoitqxGKvnd9+Pop5l1g3OmjPrP9x+H6TffH46qH5u8lfwVJBe/qwXtbpsZ33ubu/5rM+dNWfW93G397/OVW9QUce6F2P1/O77mTVHUauueoOKOta9GKvnd9/PrDmKWnXVG1TUse7FWD2/+35mzVHUqqveoKKOdS/G6vnd9zNrjqJWXfUGFXWsezFWz+++n1lzFLXqqjeoqGPdi7F6fvf9zJqjqFVXvUFFHetejNXzu+9n1hxFrbrqDb4ZfBOkvwj4MKie53HwQ/BjMOs83Yuxen73/cyaM+v7uNv7X+eqN6ioY92LsXp+9/3MmqOoVVe9QUUd616M1fO772fWHEWtuuoNKupY92Ksnt99P7PmKGrVVW9QUce6F2P1/O77mTVHUauueoOKOta9GKvnd9/PrDmKWnXVG1TUse7FWD2/+35mzVHUqqveoKKOdS/G6vnd9zNrjqJWXfUGq94Kfgqq89NvOKf/VLziZ/y/7sVYPb/7fmbNmfV93O39r3PVG6xS1F7FWD2/+35mzVHUqqveYJWi9irG6vnd9zNrjqJWXfUGqxS1VzFWz+++n1lzFLXqqjdYpai9irF6fvf9zJqjqFVXvcEqRe1VjNXzu+9n1hxFrbrqDVYpaq9irJ7ffT+z5ihq1VVvsEpRexVj9fzu+5k1R1GrrnqDnwfPB7eDh0H1PL8G7wQ3g3TO6nnSz/VqkF7+S0H63PSXFK8FTxbNeodn7WfW+R8F6fx3gvSb+dXz7Pb+11FURVXUffajqIo6d46iKqqiKqqiKurYbi9KUffcj6Iq6tw5iqqoiqqoiqqoY7u9KEXdcz+Kqqhz5yiqoiqqoiqqoo7t9qIUdc/9KKqizp0zq6gfBPeC9A1Kc6rnuRs8CO4HnwXV87wXpPP8HHwVVO8llTb95+Fbwax3eNZ+Zp3/oyC987Tn74Jng3Se3d7/OoqqqIq6z34UVVHnzlFURVVURVVURR3b7UUp6p77UVRFnTtHURVVURVVURV1bLcXpah77kdRFXXuHEVVVEVVVEVV1LHdXpSi7rkfRe1eVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjhP0tJ8Tk=');

begin
SetTargetBitmap(bmp);
DebugBitmap(bmp);
WriteLn('Original bitmap');
Wait(1000);
//thresholding the bitmap to remove "weak" colors.
//just replace bitmap with the client bitmap, covering the area of the text.
ThresholdAdaptiveBitmap(bmp, 0, 255, false, TM_MinMax, 10);
DebugBitmap(bmp);
WriteLn('Thresholded bitmap');
FreeTarget(GetImageTarget());
FreeBitmap(bmp);
end.
function ThresholdAdaptiveBitmap(bitmap:Integer; alpha, beta:Byte; invert:Boolean; ThreshMethod:SomeEnumType, Modifier: Integer);
You can instead use Tesseract, as other people has pointed out, but it's not really needed for this simple task.

There are several other possibilities for how to read that text, very quickly. But thresholding should be all you need.