# Improve TextRecognize[] on numbers

I have an image contain only numbers, and TextRecognize fail to recognize some numbers:

img=;

TextRecognize[img]
(*826718*)


The documentation says that "The quality of recognized text may improve by enlarging the image", but no luck on this example

TextRecognize[ImageResize[img, Scaled[2]]]
(*826718*)


also tried different language, also no help

TextRecognize[ImageResize[img, Scaled[2]], Language -> "French"]
(*826718*)


I also tried Walfram|Alpha, it also gave the same results as Mathematica:

Are there some ways to solve the problem?

-
After answering, I noticed this is a possible duplicate of this post which has some useful comments attached. – bobthechemist Jun 15 '13 at 2:00

TextRecognize seems to be a work in progress, consider the following

Rasterize[Graphics[Text[Style["3", 100]]]] // TextRecognize
Rasterize[Graphics[Text[Style["a", 100]]]] // TextRecognize
Rasterize[Graphics[Text[Style["123", 100]]]] // TextRecognize
Rasterize[Graphics[Text[Style["1234", 100]]]] // TextRecognize
Rasterize[Graphics[Text[Style["hello", 100]]]] // TextRecognize
Rasterize[Graphics[Text[Style["hello 3", 100]]]] // TextRecognize


yields the following output

{nothing here}
{nothing here}
{nothing here}
1234
hello
hello 3


For reasons that are entirely unclear, single characters are not recognized as text, nor are numbers small "arrays" of numbers. Oddly enough, small numbers are recognized if preceeded with an actual word, making the following a terrible solution that nonetheless gives you the answer:

n = Import["http://i.stack.imgur.com/cPRrY.png"];
pretext = Rasterize["hello ", RasterSize -> 175, ImageSize -> 40];
Row[{pretext, ImageResize[n, 1000]}] // Rasterize;
t = TextRecognize@ImageResize[%, Scaled[5]];
StringSplit@t


gives the output

{hello,3482671897}


Let's hope someone comes up with a better answer...

-
I like the last part. hello – s0rce Jun 15 '13 at 2:07
+1 "work in progress" used to mean "it's currently being worked on"; I suspect it means the opposite in this case... :) – cormullion Jun 15 '13 at 6:22

TextRecognize[] accepts an undocumented Option "SegmentationMode". The allowed values are:

?ImageExternalOCRDump\$TextRecognizeSegmentationModes

{
{{3, "Fully automatic page segmentation, but no OSD. (Default)"}},
{{4, "Assume a single column of text of variable sizes"}},
{{6, "Assume a single uniform block of text"}},
{{7, "Treat the image as a single text line"}},
{{8, "Treat the image as a single word"}},
{{10, "Treat the image as a single character"}}
}


Of course in this case we want to use mode 7:

im = Import@"http://i.stack.imgur.com/cPRrY.png"
TextRecognize[im, "SegmentationMode" -> 7]


(* "3482671897" *)


And that's it.

Now, if you don't want to use undocumented options, you've to know that TextRecognize[] works much better if you first adjust the spacing between characters:

im = Import@"http://i.stack.imgur.com/cPRrY.png"


a = ConstantArray[1 , Last@ImageDimensions@im];
newImage = Image@Transpose[Transpose[ImageData@im] //.
{x__, Longest[a..], y__} :> {x, a, a, y}]


TextRecognize@newImage

(* "3482671897" *)


Note that we are replacing the variable length vertical white strips with a minimum of 3 pixels wide with a standard separator of two pixels, as you can see here:

Image@Transpose[Transpose[ ImageData@im] //.
{x__, b : Longest[a..], y__} :> {x, 0 b, y}]


-