Skip to content

Commit

Permalink
implement ios version
Browse files Browse the repository at this point in the history
  • Loading branch information
sheppard committed May 9, 2017
1 parent 4ed34b3 commit edd152e
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 6 deletions.
31 changes: 25 additions & 6 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,38 @@
</js-module>

<platform name="android">
<config-file target="config.xml" parent="/*">
<config-file target="config.xml" parent="/*">
<feature name="TensorFlow">
<param name="android-package" value="io.wq.tensorflow.TensorFlow" />
</feature>
</config-file>
</config-file>

<source-file src="src/android/TensorFlow.java" target-dir="src/io/wq/tensorflow" />
<source-file src="src/android/tf_libs/Classifier.java" target-dir="src/org/tensorflow/demo" />
<source-file src="src/android/tf_libs/TensorFlowImageClassifier.java" target-dir="src/org/tensorflow/demo" />
<source-file src="src/android/tf_libs/libandroid_tensorflow_inference_java.jar" target-dir="libs" />
<source-file src="src/android/TensorFlow.java" target-dir="src/io/wq/tensorflow" />
<source-file src="src/android/tf_libs/Classifier.java" target-dir="src/org/tensorflow/demo" />
<source-file src="src/android/tf_libs/TensorFlowImageClassifier.java" target-dir="src/org/tensorflow/demo" />
<source-file src="src/android/tf_libs/libandroid_tensorflow_inference_java.jar" target-dir="libs" />
<source-file src="src/android/tf_libs/armeabi-v7a/libtensorflow_inference.so" target-dir="libs/armeabi" />

</platform>

<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="TensorFlow">
<param name="ios-package" value="TensorFlow" />
</feature>
</config-file>

<framework type='podspec' src='TensorflowPod' spec=":podspec => 'https://raw.githubusercontent.com/heigeo/TensorflowPod/master/TensorflowPod.podspec'"/>

<header-file src="src/ios/TensorFlow.h" />
<source-file src="src/ios/TensorFlow.mm" compiler-flags="-std=gnu++11" />

<header-file src="src/ios/tf_libs/tensorflow_utils.h" />
<source-file src="src/ios/tf_libs/tensorflow_utils.mm" compiler-flags="-std=gnu++11" />

<header-file src="src/ios/tf_libs/ios_image_load.h" />
<source-file src="src/ios/tf_libs/ios_image_load.mm" compiler-flags="-std=gnu++11" />

</platform>
</plugin>

40 changes: 40 additions & 0 deletions src/ios/TensorFlow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <memory>
#include <vector>
#include "tensorflow/core/public/session.h"

#import "ios_image_load.h"
#import "tensorflow_utils.h"
#import <Cordova/CDVPlugin.h>

@interface TensorFlow : CDVPlugin {
NSMutableDictionary *classifiers;
}

- (void)loadModel:(CDVInvokedUrlCommand*)command;
- (void)classify:(CDVInvokedUrlCommand*)command;

@end

@interface Classifier : NSObject {
std::unique_ptr<tensorflow::Session> session;
NSString* model_file;
NSString* label_file;
std::vector<std::string> labels;
int input_size;
int image_mean;
float image_std;
NSString* input_name;
NSString* output_name;
}

- (id)initWithModel:(NSString *)model_file_
label_file:(NSString *)label_file_
input_size:(int)input_size_
image_mean:(int)image_mean_
image_std:(float)image_std_
input_name:(NSString *)input_name_
output_name:(NSString *)output_name_;
- (tensorflow::Status)load;
- (tensorflow::Status)classify:(NSString *)image results:(NSMutableArray *)results;

@end
113 changes: 113 additions & 0 deletions src/ios/TensorFlow.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#import "TensorFlow.h"
#import <Cordova/CDVPlugin.h>
#import "ios_image_load.h"
#import "tensorflow_utils.h"

@implementation TensorFlow

- (void)loadModel:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* model_name = [command.arguments objectAtIndex:0];
Classifier* classifier = [
[Classifier alloc]
initWithModel:[command.arguments objectAtIndex:1]
label_file:[command.arguments objectAtIndex:2]
input_size:[(NSNumber *)[command.arguments objectAtIndex:3] intValue]
image_mean:[(NSNumber *)[command.arguments objectAtIndex:4] intValue]
image_std:[(NSNumber *)[command.arguments objectAtIndex:5] floatValue]
input_name:[command.arguments objectAtIndex:6]
output_name:[command.arguments objectAtIndex:7]
];
if (classifiers == nil) {
classifiers = [NSMutableDictionary dictionaryWithDictionary:@{}];
}
classifiers[model_name] = classifier;
tensorflow::Status result = [classifier load];
if (result.ok()) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
}

[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)classify:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* model_name = [command.arguments objectAtIndex:0];
NSString* image = [command.arguments objectAtIndex:1];
Classifier* classifier = classifiers[model_name];
NSMutableArray* results = [[NSMutableArray alloc] init];
tensorflow::Status result = [classifier classify:image results:results];
if (result.ok()) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:results];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
}

[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

@end

@implementation Classifier

- (id)initWithModel:(NSString *)model_file_
label_file:(NSString *)label_file_
input_size:(int)input_size_
image_mean:(int)image_mean_
image_std:(float)image_std_
input_name:(NSString *)input_name_
output_name:(NSString *)output_name_
{
self = [super init];
if (self) {
model_file = model_file_;
label_file = label_file_;
input_size = input_size_;
image_mean = image_mean_;
image_std = image_std_;
input_name = input_name_;
output_name = output_name_;
}
return self;
}

- (tensorflow::Status)load
{
tensorflow::Status result;
result = LoadModel(model_file, &session);
if (result.ok()) {
result = LoadLabels(label_file, &labels);
}
return result;
}

- (tensorflow::Status)classify:(NSString *)image results:(NSMutableArray *)results
{
std::vector<Result> tfresults;
tensorflow::Status result = RunInferenceOnImage(
image,
input_size,
image_mean,
image_std,
[input_name UTF8String],
[output_name UTF8String],
&session,
&labels,
&tfresults
);
if (!result.ok()) {
return result;
}
for (struct Result result : tfresults) {
[results addObject: @{
@"title": result.label,
@"confidence": result.confidence
}];
}
}

@end

0 comments on commit edd152e

Please sign in to comment.