3

I spent more than 24 hours in debugging and troubleshooting problem in tesseract, the problem that I'm looping the below function for multiple images and every time, I track the memory and I found that the memory is increased every time i call below line

Tesseract* tesseract = [[Tesseract alloc] initWithLanguage:@"eng+ita"];

and it is not impacted by below line

tesseract = nil;

below is the full function which called

    -(void)recognizeImageWithTesseract:(UIImage *)img
    {

     UIImage *testb = [img blackAndWhite];

       Tesseract* tesseract = [[Tesseract alloc] initWithLanguage:@"eng+ita"];

       tesseract.delegate = self;
         [tesseract setVariableValue:@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-/*._=':!)(" forKey:@"tessedit_char_whitelist"]; //limit search
        [tesseract setImage:testb];
        [tesseract recognize];
         recognizedText = [tesseract recognizedText];
        tesseract = nil; //deallocate and free all memory
}

UPDATE 1:

after deep troubleshooting, I discovered the tesseract code of setimage is the reason, the code as below, i need to know which code I have to update to clear this issue

- (void)setImage:(UIImage *)image {

    if (image == nil || image.size.width <= 0 || image.size.height <= 0) {
        NSLog(@"WARNING: Image has not size!");
        return;
    }

    self.imageSize = image.size; //self.imageSize used in the characterBoxes method
    int width = self.imageSize.width;
    int height = self.imageSize.height;

    CGImage *cgImage = image.CGImage;
    CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
    _pixels = CFDataGetBytePtr(data);

    size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
    size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
    size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);

    tesseract::ImageThresholder *imageThresholder = new tesseract::ImageThresholder();

    assert(bytesPerRow < MAX_INT32);
    {
        imageThresholder->SetImage(_pixels,width,height,(int)(bitsPerPixel/bitsPerComponent),(int)bytesPerRow);
        _tesseract->SetImage(imageThresholder->GetPixRect());
    }

    imageThresholder->Clear();
    CFRelease(data);
    delete imageThresholder;
    imageThresholder = nil;
}

please support me to solve this problem

thanks alot

Soliton
  • 31
  • 3

1 Answers1

0

You're doing this in a tight loop, and memory is released after each application run loop. What you need to do is

// your loop here 
for (int i = 0; i < n; i++) {
    @autoreleasepool {
        // perform memory intensive task here;
    }
}

So every time the memory autorelease pool is drained after your heavy task.

Read here for more details:

Objective-C: Why is autorelease (@autoreleasepool) still needed with ARC?

Community
  • 1
  • 1
X.Y.
  • 13,726
  • 10
  • 50
  • 63
  • after test, I found the memory increase steps become low (about 5M only for each loop) but for long loops, it make the app crash, please support to consider this answer is the best answer – Soliton Nov 02 '14 at 23:24
  • Then some other part went wrong, which should be a separate question. Your loop memory release issue solution is simply @autoreleasepool. – X.Y. Nov 02 '14 at 23:38