-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathRecognizer.mm
78 lines (65 loc) · 2.42 KB
/
Recognizer.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#import "Recognizer.h"
#import "../../utils/ImageProcessor.h"
#import "RecognizerUtils.h"
#import "utils/OCRUtils.h"
/*
The model used as detector is based on CRNN paper.
https://arxiv.org/pdf/1507.05717
*/
@implementation Recognizer {
cv::Size originalSize;
}
- (cv::Size)getModelImageSize {
NSArray *inputShape = [module getInputShape:@0];
NSNumber *widthNumber = inputShape.lastObject;
NSNumber *heightNumber = inputShape[inputShape.count - 2];
const int height = [heightNumber intValue];
const int width = [widthNumber intValue];
return cv::Size(height, width);
}
- (cv::Size)getModelOutputSize {
NSArray *outputShape = [module getOutputShape:@0];
NSNumber *widthNumber = outputShape.lastObject;
NSNumber *heightNumber = outputShape[outputShape.count - 2];
const int height = [heightNumber intValue];
const int width = [widthNumber intValue];
return cv::Size(height, width);
}
- (NSArray *)preprocess:(cv::Mat &)input {
return [ImageProcessor matToNSArrayGray:input];
}
- (NSArray *)postprocess:(NSArray *)output {
const int modelOutputHeight = [self getModelOutputSize].height;
NSInteger numElements = [output.firstObject count];
NSInteger numRows = (numElements + modelOutputHeight - 1) / modelOutputHeight;
cv::Mat resultMat = cv::Mat::zeros(numRows, modelOutputHeight, CV_32F);
NSInteger counter = 0;
NSInteger currentRow = 0;
for (NSNumber *num in output.firstObject) {
resultMat.at<float>(currentRow, counter) = [num floatValue];
counter++;
if (counter >= modelOutputHeight) {
counter = 0;
currentRow++;
}
}
cv::Mat probabilities = [RecognizerUtils softmax:resultMat];
NSMutableArray *predsNorm =
[RecognizerUtils sumProbabilityRows:probabilities
modelOutputHeight:modelOutputHeight];
probabilities = [RecognizerUtils divideMatrix:probabilities
byVector:predsNorm];
NSArray *maxValuesIndices =
[RecognizerUtils findMaxValuesAndIndices:probabilities];
const CGFloat confidenceScore =
[RecognizerUtils computeConfidenceScore:maxValuesIndices[0]
indicesArray:maxValuesIndices[1]];
return @[ maxValuesIndices[1], @(confidenceScore) ];
}
- (NSArray *)runModel:(cv::Mat &)input {
NSArray *modelInput = [self preprocess:input];
NSArray *modelResult = [self forward:modelInput];
NSArray *result = [self postprocess:modelResult];
return result;
}
@end