Archive for 9月, 2013
Salesforce Mobile SDKに光学文字認識を組み込む方法
個人的にOCR(光学文字認識)には強い関心を抱いています。この機能が実用アプリにもたらすブレークスルーは可能性に富んでいると考えているからです。
例えば役所では毎日とんでもない量の用紙が記入され、その情報を手入力でデータ化するという作業がおこなわれています。この作業がOCRで自動化されればどういうインパクトがあるか、容易に想像できます。
ユースケースを考えるときりがない程ですが、今回はスマートフォンを利用する、という前提で考えてみたいと思います。カメラを搭載したスマートフォンはOCRを様々なシチュエーションで実行することを可能にするデバイスです。今回はOCR機能を組み込んだビジネスアプリを開発することを前提にしたTipsをご紹介しようと思います。
実用的なビジネスアプリといえばForce.com。Force.comでモバイルアプリを開発するならSalesforce Mobile SDK。ということでSalesforce Mobile SDKにOCR機能を組み込むにはどうすればいいか、その手順をみていきます。
スマートフォンはiPhone 5、そして最も重要なOCR機能を実施するエンジンには、オープンソースで精度に定評のあるTessearct OCRを採用します。
環境
- iPhone 5 – iOS SDK 6.1
- Salesforce Mobile SDK – 2.0
- Tessract OCR – 3.02.02
Salesforce Mobile SDKのインストール
まず、なにはなくともSalesforce Mobile SDKをインストールします。 こちらに記載されている手順通りにインストールをおこないます。
http://www2.developerforce.com/mobile/getting-started/ios
Tesseract OCRのインストール
クラスメソッドさんが詳細な手順をブログに記載されていますのでこちらで紹介されている通りにインストールをおこないます。
http://dev.classmethod.jp/etc/ios-tesseract-ocr/
ちなみに僕はbuild_dependencies.shの環境設定でIOS_DEPLOY_TARGETは下記のように書き換えました。
IOS_BASE_SDK="6.1" IOS_DEPLOY_TGT="6.1"
プロジェクトの作成と設定
次にSalesforce Mobile SDKを使って新規プロジェクトを作成します。ターミナルからforceiosコマンドを実行します。appnameをはじめオプションは適当な値に変えていただいて問題ありません。
forceios create --apptype="native" --appname="ocrtest" --companyid="com.mydomain" --organization="My Company" --outputdir="$HOME/Workspaces/xcode" --packagename="com.mydomain.ocrtest"
Xcodeで今作成したプロジェクトをオープンします。プロジェクトの構成は下図のようになっているはずです。
Dependenciesフォルダを右クリックし、「New Group」を選択します。フォルダが作成されますのでTesseractと入力します。
ターミナルを開き下記のようにTesseractディレクトリを作成し、先の手順でビルドしたincludeとlibディレクトリをTesseractディレクトリ直下に移動させます。
cd $HOME/Workspaces/xcode/ocrtest/Dependencies/ mkdir Tesseract mv PATH/TO/tesseract-iOS6.1-build/dependencies/inlucde ./Tesseract/ mv PATH/TO/tesseract-iOS6.1-build/dependencies/lib ./Tesseract/
XcodeでTesseractフォルダを右クリックし、Add Files to “ocrtest”を選択し、移動させた下記2つのフォルダを追加します。オプションについてはスクリーンショットを参照してください。
- $HOME/Workspaces/xcode/ocrtest/Dependencies/Tesseract/include
- $HOME/Workspaces/xcode/ocrtest/Dependencies/Tesseract/lib
次にTesseractのObjective-C Wrapperをインポートします。下記Githubのレポジトリからzipファイルでソース全体をダウンロードし、解凍します。
https://github.com/ldiqual/tesseract-ios
ターミナルで解凍したフォルダ中2つのファイルを移動します。
mv PATH/TO/tesseract-ios-master/Classes/Tesseract.h ./Tesseract/ mv PATH/TO/tesseract-ios-master/Classes/Tesseract.mm ./Tesseract/
XcodeでTesseractフォルダを右クリックし、Add Files to “ocrtest”を選択し、移動した下記2つのファイルを追加します。オプションについてはスクリーンショットを参照してください。
- $HOME/Workspaces/xcode/ocrtest/Dependencies/Tesseract/Tesseract.h
- $HOME/Workspaces/xcode/ocrtest/Dependencies/Tesseract/Tesseract.mm
言語ファイルをインポートします。今回は英語を対象とし、下記のファイルをダウンロードして解凍します。
http://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz
解凍したフォルダ中のtessdataフォルダを移動します。
mv PATH/TO/tesseract-ocr/tessdata ./Tesseract/
XcodeでTesseractフォルダを右クリックし、Add Files to “ocrtest”を選択し、移動したtessdataフォルダを追加します。オプションについてはスクリーンショットを参照してください。
プロジェクトのBuild Settingsを下記のように変更します。
- C++ Language Dialect => Compiler Default
- C++ Standard Library => Compiler Default
- Other Linker Flags => -ObjC
ここで一旦Runボタンをクリックし、シミュレーターでアプリを起動してみてください。エラーがでなければOKです。
文字認識の実行
RootViewControllerでTesseractライブラリを呼び出せるようにRootViewController.hを編集します。
#import #import "SFRestAPI.h" #import "Tesseract.h" @interface RootViewController : UITableViewController<SFRestDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate> { NSMutableArray *dataRows; IBOutlet UITableView *tableView; } @property (nonatomic, strong) NSArray *dataRows; @end
次にRootViewController.mを編集し、アプリケーション起動直後にカメラを起動するようにします。また、撮影した画像をTesseractで解析し、抽出した文字列をログに出力させます。
- (void)viewDidLoad { [super viewDidLoad]; self.title = @"Mobile SDK Sample App"; //カメラを起動 [self showUIImagePicker]; } - (void)showUIImagePicker { if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){ return; } UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.delegate = self; imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; imagePickerController.allowsEditing = YES; [self presentViewController:imagePickerController animated:YES completion:nil]; } - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo { [self dismissViewControllerAnimated:NO completion:nil]; Tesseract *tess = [[Tesseract alloc] initWithDataPath:@"tessdata" language:@"eng"]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [tess setImage:image]; [tess recognize]; dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%@", [NSString stringWithFormat:@"%@", [tess recognizedText]]); }); }); } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [self dismissViewControllerAnimated:YES completion:nil]; }
シミュレーターではカメラが起動できないので、実際のiPhoneで動作を確認してみてください。アプリケーションの起動とともにカメラが起動し、撮影が完了した後に解析が完了次第ログに抽出された文字列が出力されます。
もしすぐにiPhoneにアプリをデプロイできない場合は、一時的にシミュレーターのカメラロールを利用する方法で動作確認をおこなうことができます。
まずshowImagePickerControllerを下記のように修正し、カメラを起動するかわりにカメラロールから写真を選択できるようにします。
- (void)showUIImagePicker { if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){ return; } UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.delegate = self; imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; imagePickerController.allowsEditing = YES; [self presentViewController:imagePickerController animated:YES completion:nil]; }
次にシミュレーターを起動し、シミュレーターの画面にテストしたい画像をドラッグ&ドロップします。Safariが起動して画像が読み込まれます。読み込まれた画像を長押しするとカメラロールに画像を保存できます。
これで準備OKです。シミュレーターを再起動し、保存した写真を選択すれば解析がおこなわれるはずです。