Skip to content

Commit a973a6c

Browse files
author
Kevin Conley
committed
Merge pull request #160 from kevincon/fix-orientation
Image orientation fix. Fixes #151. Fixes #130.
2 parents 87614be + 661d210 commit a973a6c

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ DEPENDENCIES:
55
- Kiwi (~> 2.3.1)
66

77
SPEC CHECKSUMS:
8-
Kiwi: 73e1400209055ee9c8ba78c6012b6b642d0fb9f7
8+
Kiwi: f038a6c61f7a9e4d7766bff5717aa3b3fdb75f55
99

10-
COCOAPODS: 0.36.0.beta.1
10+
COCOAPODS: 0.36.1

Tesseract OCR iOS.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
413F03321A5FBBDD000C194B /* UIImage+G8FixOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = 413F03301A5FBBDD000C194B /* UIImage+G8FixOrientation.h */; };
11+
413F03331A5FBBDD000C194B /* UIImage+G8FixOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = 413F03311A5FBBDD000C194B /* UIImage+G8FixOrientation.m */; };
1012
73C0A7961A5932C400D823D4 /* G8Tesseract.h in Headers */ = {isa = PBXBuildFile; fileRef = 64A029D617307CD0002B12E7 /* G8Tesseract.h */; settings = {ATTRIBUTES = (Public, ); }; };
1113
73C0A7971A5932C800D823D4 /* G8Tesseract.mm in Sources */ = {isa = PBXBuildFile; fileRef = 64A029D717307CD0002B12E7 /* G8Tesseract.mm */; };
1214
73C0A7981A5932CC00D823D4 /* G8TesseractDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4141211F1A4C578800583ED4 /* G8TesseractDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -25,6 +27,8 @@
2527
/* End PBXBuildFile section */
2628

2729
/* Begin PBXFileReference section */
30+
413F03301A5FBBDD000C194B /* UIImage+G8FixOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+G8FixOrientation.h"; sourceTree = "<group>"; };
31+
413F03311A5FBBDD000C194B /* UIImage+G8FixOrientation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+G8FixOrientation.m"; sourceTree = "<group>"; };
2832
4141211F1A4C578800583ED4 /* G8TesseractDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = G8TesseractDelegate.h; sourceTree = "<group>"; };
2933
418997A71A42CC8B00D6477C /* G8Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = G8Constants.h; sourceTree = "<group>"; };
3034
41A95DE81A3AF39B0085093C /* G8TesseractParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = G8TesseractParameters.h; sourceTree = "<group>"; };
@@ -246,6 +250,8 @@
246250
418997A71A42CC8B00D6477C /* G8Constants.h */,
247251
6490748A198A5A5600D728CC /* UIImage+G8Filters.h */,
248252
6490748B198A5A5600D728CC /* UIImage+G8Filters.m */,
253+
413F03301A5FBBDD000C194B /* UIImage+G8FixOrientation.h */,
254+
413F03311A5FBBDD000C194B /* UIImage+G8FixOrientation.m */,
249255
41C7E8231A3F0682000DC42B /* Core */,
250256
41C7E8211A3F0650000DC42B /* Readme */,
251257
64A0293017307C1D002B12E7 /* Supporting Files */,
@@ -465,6 +471,7 @@
465471
isa = PBXHeadersBuildPhase;
466472
buildActionMask = 2147483647;
467473
files = (
474+
413F03321A5FBBDD000C194B /* UIImage+G8FixOrientation.h in Headers */,
468475
73C0A7961A5932C400D823D4 /* G8Tesseract.h in Headers */,
469476
73C0A79D1A5932F900D823D4 /* G8TesseractParameters.h in Headers */,
470477
73C0A7A01A59330A00D823D4 /* UIImage+G8Filters.h in Headers */,
@@ -548,6 +555,7 @@
548555
73C0A7A11A59330E00D823D4 /* UIImage+G8Filters.m in Sources */,
549556
73C0A79C1A5932F500D823D4 /* G8RecognitionOperation.m in Sources */,
550557
73C0A7971A5932C800D823D4 /* G8Tesseract.mm in Sources */,
558+
413F03331A5FBBDD000C194B /* UIImage+G8FixOrientation.m in Sources */,
551559
73C0A79E1A5932FD00D823D4 /* G8TesseractParameters.m in Sources */,
552560
);
553561
runOnlyForDeploymentPostprocessing = 0;

TesseractOCR/G8Tesseract.mm

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#import "G8Tesseract.h"
1111

1212
#import "UIImage+G8Filters.h"
13+
#import "UIImage+G8FixOrientation.h"
1314
#import "G8TesseractParameters.h"
1415
#import "G8Constants.h"
1516
#import "G8RecognizedBlock.h"
@@ -375,6 +376,8 @@ - (void)setImage:(UIImage *)image
375376
return;
376377
}
377378

379+
image = [image fixOrientation];
380+
378381
self.imageSize = image.size; //self.imageSize used in the characterBoxes method
379382

380383
Pix *pix = nullptr;
@@ -490,43 +493,48 @@ - (NSString *)recognizedText
490493
- (G8Orientation)orientation
491494
{
492495
if (self.layoutAnalysed == NO) {
493-
[self analyzeLayout];
496+
[self analyseLayout];
494497
}
495498
return _orientation;
496499
}
497500

498501
- (G8WritingDirection)writingDirection
499502
{
500503
if (self.layoutAnalysed == NO) {
501-
[self analyzeLayout];
504+
[self analyseLayout];
502505
}
503506
return _writingDirection;
504507
}
505508

506509
- (G8TextlineOrder)textlineOrder
507510
{
508511
if (self.layoutAnalysed == NO) {
509-
[self analyzeLayout];
512+
[self analyseLayout];
510513
}
511514
return _textlineOrder;
512515
}
513516

514517
- (CGFloat)deskewAngle
515518
{
516519
if (self.layoutAnalysed == NO) {
517-
[self analyzeLayout];
520+
[self analyseLayout];
518521
}
519522
return _deskewAngle;
520523
}
521524

522-
- (void)analyzeLayout
525+
- (void)analyseLayout
523526
{
524527
tesseract::Orientation orientation;
525528
tesseract::WritingDirection direction;
526529
tesseract::TextlineOrder order;
527530
float deskewAngle;
528531

529532
tesseract::PageIterator *iterator = _tesseract->AnalyseLayout();
533+
if (iterator == NULL) {
534+
NSLog(@"Can't analyse layout. Make sure 'osd.traineddata' available in 'tessdata'.");
535+
return;
536+
}
537+
530538
iterator->Orientation(&orientation, &direction, &order, &deskewAngle);
531539
delete iterator;
532540

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// UIImage+G8FixOrientation.h
3+
// Tesseract OCR iOS
4+
//
5+
// Thanks to `an0` for answer from
6+
// http://stackoverflow.com/a/10611036
7+
//
8+
// Created by Nikolay Volosatov on 09/01/15.
9+
// Copyright (c) 2014 Daniele Galiotto - www.g8production.com.
10+
// All rights reserved.
11+
//
12+
13+
#import <UIKit/UIKit.h>
14+
15+
@interface UIImage (G8FixOrientation)
16+
17+
- (UIImage *)fixOrientation;
18+
19+
@end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// UIImage+G8FixOrientation.m
3+
// Tesseract OCR iOS
4+
//
5+
// Thanks to `an0` for answer from
6+
// http://stackoverflow.com/a/10611036
7+
//
8+
// Created by Nikolay Volosatov on 09/01/15.
9+
// Copyright (c) 2014 Daniele Galiotto - www.g8production.com.
10+
// All rights reserved.
11+
//
12+
13+
#import "UIImage+G8FixOrientation.h"
14+
15+
@implementation UIImage (G8FixOrientation)
16+
17+
- (UIImage *)fixOrientation
18+
{
19+
// No-op if the orientation is already correct
20+
if (self.imageOrientation == UIImageOrientationUp) return self;
21+
22+
UIImage *result;
23+
24+
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
25+
26+
[self drawInRect:(CGRect){0, 0, self.size}];
27+
result = UIGraphicsGetImageFromCurrentImageContext();
28+
29+
UIGraphicsEndImageContext();
30+
31+
return result;
32+
}
33+
34+
@end

TestsProject/TestsProjectTests/RecognitionTests.m

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,25 @@
5959
[[recognizedText should] containString:@"1234567890"];
6060
});
6161

62+
it(@"Should recognize regardless of orientation", ^{
63+
UIImage *image = helper.image;
64+
UIImage *rotatedImage = [UIImage imageWithCGImage:image.CGImage
65+
scale:image.scale
66+
orientation:UIImageOrientationLeft];
67+
68+
[[theValue(image.imageOrientation) shouldNot] equal:theValue(rotatedImage.imageOrientation)];
69+
70+
[[theBlock(^{
71+
[helper recognizeImage];
72+
}) shouldNot] raise];
73+
74+
NSString *recognizedText = helper.tesseract.recognizedText;
75+
[[recognizedText should] containString:@"1234567890"];
76+
77+
UIImage *thresholdedImage = helper.tesseract.thresholdedImage;
78+
[[theValue(thresholdedImage.imageOrientation) should] equal:theValue(UIImageOrientationUp)];
79+
});
80+
6281
describe(@"Subimage", ^{
6382

6483
beforeEach(^{
@@ -226,6 +245,16 @@
226245
[[theValue([onceThresholded g8_isEqualToImage:twiceThresholded]) should] beYes];
227246
});
228247

248+
it(@"Should not crash analyze layout", ^{
249+
helper.pageSegmentationMode = G8PageSegmentationModeOSDOnly;
250+
251+
[helper recognizeImage];
252+
253+
[[theBlock(^{
254+
[helper.tesseract deskewAngle];
255+
}) shouldNot] raise];
256+
});
257+
229258
it(@"Should analyze layout", ^{
230259
helper.pageSegmentationMode = G8PageSegmentationModeAutoOSD;
231260

0 commit comments

Comments
 (0)