5
votes

I have used Tesseract OCR iOS to scan text, and I have gotten it to work with a photo included in the project.

But when passing it a UIImage from the UIImagePickerController, it does not work. I set up this simple test:

  1. Take the original image from the picker, and feed it to tesseract: Does not work.
  2. Save the UIImage as JPEG, copy it from the app container, include it in the project and feed it to tesseract: Does not work.
  3. Open the saved UIImage in photoshop, and save it again (no changes with default JPEG quality 12 settings). Include it in the project at feed it to tesseract: Works?!?

Tesseract does recognize the correct amount of lines in the original, but as garbage (i tested several example tests). Once saved in Photoshop the image has a good recognition rate.

I simply cannot figure out what is wrong with the original UIImage that Photoshop somehow fixes. Please help!

Here are the images:

The code for feeding images to tesseract:

- (void)recognizeWithImage:(UIImage *)image {
    G8RecognitionOperation *operation = [[G8RecognitionOperation alloc] initWithLanguage:@"dan"];
    operation.tesseract.image = image;
    self.imageView.image = image;
    operation.recognitionCompleteBlock = ^(G8Tesseract *recognizedTesseract) {
        NSLog(@"Result:\n%@", [recognizedTesseract recognizedText]);
    };
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:operation];
}

Here is the code for getting the image from camera:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [self dismissViewControllerAnimated:YES completion:nil];
    UIImage *originalImage = info[UIImagePickerControllerOriginalImage];

    NSData *dataForJPEGFile = UIImageJPEGRepresentation(originalImage, 1.0);
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *filePath = [paths[0] stringByAppendingPathComponent:@"temp_ocr_image_orig.jpg"];
    [dataForJPEGFile writeToFile:filePath atomically:YES];

    [self recognizeWithImage:originalImage];
}

And the testing of the two image files:

[self recognizeWithImage:[UIImage imageNamed:@"temp_ocr_image_orig.jpg"]];
[self recognizeWithImage:[UIImage imageNamed:@"temp_ocr_image_photoshopped.jpg"]];
1
what about the image sizes? are those two images of same size when u pass them to the method recogniseWIthImage ?Teja Nandamuri
Try using different engine settings, and try for png image. For more info raywenderlich.com/93276/implementing-tesseract-ocr-iosTeja Nandamuri
Sizes are the same, and both images display nicely in a UIImageView. Different engine settings and language packs make no difference. PNG doesn't help eitherSune
so whats the @"Result:\n%@", in both cases ?Teja Nandamuri
Wrong: I, 1591 ;02195591Sune

1 Answers

3
votes

The image orientation is different for both the images.When you load the images into the engine:In your case both the images are produced as images with different orientations to the engine:

Here is how they look infront of the engine:

Original Image:

enter image description here

Photoshop image:

enter image description here

If you look closely, they both are presented differently.I believe UIImageJPEGRepresentation is doing something crazy or when you are writing the image to the container, the image gets into different orientation.

You need way to modify the orientation of image that you get from the picker or from your container .

I did some combinations to get the correct orientation as the photoshop image:

                                                   //image is the original image
UIImage *imageToDisplay =[UIImage imageWithCGImage:[image CGImage]
                    scale:1.0
              orientation: UIImageOrientationRight];

UIImage *newImage=  [UIImage imageWithCGImage:[imageToDisplay CGImage]
                     scale:1.0
              orientation: UIImageOrientationDown];


UIImage *newImage2=  [UIImage imageWithCGImage:[newImage CGImage]
                                        scale:1.0
                                  orientation: UIImageOrientationLeft];

//Now I get the correct orientation

// Set the image on which Tesseract should perform recognition
operation.tesseract.image = newImage2 ;

And now you can get the text from OCR as expected.

You should try to get the correct orientation in one line of code. I have used 3 rotations here.