Google Code で公開されている Tesseract OCR を用いて、手軽に文字認識(OCR)アプリを作ってみます。
使用したもの
Xcode5.1 (iOS SDK 7.1)
今回は手間をなくすため、iOS 向けのラッパークラスが用意された Tesseract-OCR-iOS を使用します。
Tesseract-OCR-iOS
ライブラリのインストール
Tesseract-OCR-iOS を導入するために、ライブラリ管理ツール CocoaPods をインストールします。(要 Ruby)
コンソールを開き、以下のコマンドを入力してください。
sudo gem install cocoapods
pod setup
プロジェクトの作成
Xcode を開いて、ベースとなるプロジェクトを作成します。
iOSの「Single View Application」で作成してください。
(今回は Product Name を SampleOCR にしました)
プロファイルの作成
Cocoa Pods 用のプロファイルを作成します。
Empty ファイル を Podfile という名前で作成し、以下の設定を記述してください。
platform :ios, ‘5.0’ pod ‘TesseractOCRiOS’, ‘~> 2.3’
ここで、Xcode は一旦終了してください。
ライブラリの組み込み
コンソールを開き、以下のコマンドで、ワークスペースへ移動し、TesseractOCRiOS をプロジェクトに取り込んでください。
cd [ワークスペースパス] pod install
ワークスペース内に新しく SampleOCR.xcworkspace が作成された状態になると思います。
今後プロジェクトを編集する際にはこのファイルを開いてください。
ストーリーボードの編集
初めに Main.storyboard を開き、以下のコントロールを設置します。
Toolbar (Bar Button Items 付き)
Image View
Text View
続いて、ビューとの紐付けを指定します。
Bar Button から ViewController.m へ Sent Actions を追加します。
Image View および Text View から ViewController.h へ Referencing Outlets を追加します。
ソースコードの実装
ViewController.h と ViewController.m を以下の通り実装します。
ViewController.h
// 変更前
// @interface ViewController : UIViewController
// 変更後
@interface ViewController : UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
ViewController.m
@interface ViewController () @property (nonatomic, strong) UIImage *selectedImage; // イメージ @property (nonatomic, strong) UIView *loadingView; // ローディング用ビュー @property (nonatomic, strong) UIActivityIndicatorView *indicator; // ローディングインジケータ @end
// 中略
// カメラボタン押下 – (IBAction)tappedCamera:(id)sender { UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; // デリゲート指定 [imagePickerController setDelegate:self]; // トリミング指定 [imagePickerController setAllowsEditing:YES]; // カメラの使用有無を確認 if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) { // カメラを指定 [imagePickerController setSourceType:UIImagePickerControllerSourceTypeCamera]; } else { // アルバムを指定 [imagePickerController setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum]; }
// コントローラ起動 [self presentViewController:imagePickerController animated:YES completion:nil]; }
// コントローラ終了 – (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { // イメージをメモリに保存 self.selectedImage = [info objectForKey:UIImagePickerControllerEditedImage]; // イメージビューに画像をセット [self.imageView setImage:self.selectedImage]; // 親ビューへ戻る [self dismissViewControllerAnimated:YES completion:nil];
// テキストを空に [self.textView setText:nil];
// インジケータ開始 UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; spinner.center = CGPointMake(160, 240); spinner.hidesWhenStopped = YES; [self.view addSubview:spinner]; [spinner startAnimating];
// OCR実行 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 英語 : eng を設定 (日本語の場合は jpn を指定) Tesseract* tesseract = [[Tesseract alloc] initWithLanguage:@”eng”];
// OCRを実行する画像を設定 [tesseract setImage:self.selectedImage];
// OCR実行 [tesseract recognize];
// 実行結果をアラートビューで表示 dispatch_async(dispatch_get_main_queue(), ^{ // 結果をテキストビューに指定 [self.textView setText:[tesseract recognizedText]]; // インジケータ停止 [spinner stopAnimating]; }); }); }
ランゲージファイルの登録
Tesseract OCR を動かすのに必要なランゲージファイルを追加します。
以下から必要な言語のアーカイブを取得し、ローカルに一時的に展開します。
今回は英語のみ対応させるため、tesseract-ocr-*.**.eng.tar.gz を使用します。
tessdata というディレクトリが展開されるので、これを Xcode のプロジェクトにドラッグし、「Create folder references for any added folders」にチェックを入れ、ディレクトリを追加してください。
※なお、複数の言語ファイルを登録したいときは、tessdata ディレクトリ直下にファイルをまとめてください。
これでビルドを行うと、OCRアプリが完成します。
実際に試してみて
実際に試してみましょう。 アプリを起動し、ツールバーのボタンを押下します。(ボタンの Identifier に Camera をセットしています)
カメラモードになるので、対象を撮影し、正方形でトリミングしてください。 (エミュレータで実行中の場合はアルバムから写真を選択)
成功すると、画面上部に撮影写真が表示され、その下にOCRでの読み取り結果が表示されます。
実際に試してみると、傾きがなく、背景と文字がはっきりしている画像はかなりの精度で読み込めます。
一方、背景が単一色でない場合は、精度が極端に落ちます。
また、背景に文字以外の要素が入り込むと、無理やり文字に変換しようとするので、ノイズが入ります。
実用性を高めるには、適切な画像処理を行い、背景と文字を区別できるようにすることと、文字以外のものが入らないようにする工夫が必要になります。
今回は英語のみ対象としましたが、日本語ランゲージファイルを読み込ませることで、漢字も含めた読み込みができます。
Comments