24
votes

I'm trying to use Tesseract OCR library in my iOS application. I downloaded tesseract-ios library from github and when I tried to recognize a simple text image I got garbage instead. Here is an image of what I tried to recognize:

enter image description here

I got unreadable text:

T0I1101T0W KIR1 H1I1101T0W KIR1 H1I1101T0W CIBEPS H1 ES PBHY P306 EHH11 133I R1 11335 11I1H1 19 13S SYIL 3B19 M H300H1911 H1113 AIR1 J1 OIII 3I9SH5H133IS 13V9 I1 Q1H211 E015 19 W331 H1 111SW

Why Tesseract can't recognise even simple image? Here is code which I used to instantiate Tesseract:

Tesseract* tesseractObject = [[Tesseract alloc] initWithDataPath:@"tessdata" language:@"eng"];
[tesseractObject setVariableValue:@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" forKey:@"tessedit_char_whitelist"];
[tesseractObject setImage:image];
[tesseractObject recognize];
NSLog(@"RECOGNISED= %@" , [tesseractObject recognizedText]);

Here is my project structure:

enter image description here

I added English testdata folder by reference. So what am I doing wrong? How can I fix this?

5
do you have all the eng tessdata files included as it looks like your language files are not working as it is scanning and getting letter shapesAdam Richardson
@AdamRichardson see my edits please.MainstreamDeveloper00
Where do you get the image from, is it part of your app bundle, downloaded from a website by the app or is it from the camera?Adam Richardson
Have you tried it without [tesseractObject setVariableValue:@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" forKey:@"tessedit_char_whitelist"]; as that is something that I dont have in my codeAdam Richardson
Perhaps you should try again, but this time include lower case letters in the whitelist...Anders Johansen

5 Answers

21
votes

You are using the option tessedit_char_whitelist with the value "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" which limits the character recognition to this list only. However the image that you want to process contains lower case characters, if you want to use this option you will have to include lower cases char too.

[tesseractObject setVariableValue:@"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" forKey:@"tessedit_char_whitelist"];
19
votes

Make sure you have the latest tessdata file from Google code

http://code.google.com/p/tesseract-ocr/downloads/list

This will provide you with a list of tessdata files that you need to download and include in your app if you haven't already. In your case you will need tesseract-ocr-3.02.eng.tar.gz as you are looking for the English language files

The following article will show you where you need to install it. I read through this tutorial when I built my first Tesseract project and found it really useful

http://lois.di-qual.net/blog/install-and-use-tesseract-on-ios-with-tesseract-ios/

12
votes

Like Adam said, if you want good results, you'll have to do some image processing and configure some settings (white-listing certain characters, etc).

For anyone else stumbling upon this question, I've put together a sample project here that does some white-listing and image processing:https://github.com/mstrchrstphr/OCR-iOS-Example

0
votes

enter image description here

and my output is

enter image description here

Solution :

 tesseract.language = @"eng+fra";

tesseract.pageSegmentationMode = G8PageSegmentationModeAuto;
tesseract.engineMode  = G8OCREngineModeTesseractCubeCombined;
tesseract.image = [image.image g8_blackAndWhite];

tesseract.maximumRecognitionTime = 60.0;
[tesseract recognize];

NSLog(@"%@", tesseract.recognizedText);

reco_area.text = [tesseract recognizedText];

for tessdata click here

0
votes

whatever @ Adam Richardson explained is correct along with that add this 1) scaleimage method for increase size of the image(dimensions increase)

func scaleImage(image: UIImage, maxDimension: CGFloat) -> UIImage {

    var scaledSize = CGSize(width: maxDimension, height: maxDimension)
    var scaleFactor: CGFloat

    if image.size.width > image.size.height {
        scaleFactor = image.size.height / image.size.width
        scaledSize.width = maxDimension
        scaledSize.height = scaledSize.width * scaleFactor
    } else {
        scaleFactor = image.size.width / image.size.height
        scaledSize.height = maxDimension
        scaledSize.width = scaledSize.height * scaleFactor
    }

    UIGraphicsBeginImageContext(scaledSize)
    image.draw(in: CGRect(x: 0, y: 0, width: scaledSize.width, height: scaledSize.height))
    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return scaledImage!
}

2) store this eng.traineddata language file in filemanager

 func storeLanguageFile() throws{
    var fileManager: FileManager = FileManager.default
    let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
    let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
    let docDirectory = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)[0] as NSString
    let path: String = docDirectory.appendingPathComponent("/tessdata/eng.traineddata")
    if fileManager.fileExists(atPath: path){
        var data: NSData = NSData.dataWithContentsOfMappedFile((Bundle.main.resourcePath?.appending("/tessdata/eng.traineddata"))!)! as! NSData
        var error: NSError
        try FileManager.default.createDirectory(atPath: docDirectory.appendingPathComponent("/tessdata"), withIntermediateDirectories: true, attributes: nil)
        data.write(toFile: path, atomically: true)
    }
}

3) after that you can use https://github.com/BradLarson/GPUImage for increase clarity of the image

you can use this

func preprocessedImage(for tesseract: G8Tesseract!, sourceImage: UIImage!) -> UIImage! {
    var stillImageFilter: GPUImageAdaptiveThresholdFilter = GPUImageAdaptiveThresholdFilter()
    stillImageFilter.blurRadiusInPixels = 4.0
    var filterImage: UIImage = stillImageFilter.image(byFilteringImage: sourceImage)
    return filterImage
}

these 3 steps will help you to increase the accuracy of the tesseract upto 60 ~ 70 %