[{"data":1,"prerenderedAt":288},["ShallowReactive",2],{"news-item-\u002Fja\u002Fnews\u002Ftesseract-ios":3},{"id":4,"title":5,"body":6,"category":273,"created by":276,"date":277,"description":278,"extension":279,"meta":280,"navigation":281,"path":282,"sections":283,"seo":284,"stem":285,"thumbnail":286,"__hash__":287},"content_ja\u002Fja\u002Fnews\u002Ftesseract-ios.md","Tesseract iOSへの導入について",{"type":7,"value":8,"toc":265},"minimark",[9,13,21,24,32,35,42,45,48,67,71,74,84,89,96,102,105,110,114,121,125,128,132,137,144,155,158,162,166,169,173,177,180,183,193,196,202,205,213,215,221,224,230,233,237,240,246,249,253,256,259],[10,11,12],"h2",{"id":12},"最初に",[14,15,16,20],"p",{},[17,18,19],"strong",{},"Tesseract","は様々なオペレーティングシステムで動作する\"optical character recognition(光学式文字認識)\"エンジンです。これはフリーソフトウェアでApacheライセンスの元提供されております。そしてGoogleが2006年から2020年現在までスポンサーとなってます。これは最もポピュラーで最も正確なOCRライブラリです。テキスト検索や画像認識のための人工知能(AI)として利用されます。 これは様々なプラットフォームをサポートしています。MacOS, Window, LinuxだけでなくiOS and Androidも含まれます。 ",[14,22,23],{},"これはリポジトリのプログラムです。",[14,25,26],{},[27,28,29],"a",{"href":29,"rel":30},"https:\u002F\u002Fgithub.com\u002Ftesseract-ocr\u002Ftesseract",[31],"nofollow",[14,33,34],{},"100種類以上の言語をサポートしています。それぞれの\".traineddata\"ファイルは言語トレーニングモデルです。",[14,36,37,41],{},[27,38,39],{"href":39,"rel":40},"https:\u002F\u002Fgithub.com\u002Ftesseract-ocr\u002Ftessdata",[31]," ",[14,43,44],{},"今回TesseractのiOS版の実施の仕方について説明したいと思います。",[10,46,47],{"id":47},"開発環境",[49,50,51,55,58,61,64],"ul",{},[52,53,54],"li",{},"Macos Catalina 10.15.2",[52,56,57],{},"Xcode 11.3, Swift 5",[52,59,60],{},"Tesseract 4.1.1",[52,62,63],{},"Leptonica 1.79.0",[52,65,66],{},"OpenCV 4.2.0",[10,68,70],{"id":69},"関連のものをダウンロードします","関連のものをダウンロードします。",[14,72,73],{},"最初に、\"Single View App mode\"でプロジェクトを作成します。",[75,76],"img",{"className":77,"alt":81,"src":82,"style":83},[78,79,80],"block","mx-auto","mb-4","","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06172932\u002FScreen-Shot-2020-01-13-at-2.23.57-PM-1024x737.png","width: 100%;",[85,86,88],"h4",{"id":87},"tesseract-411-ios版をダウンロード","tesseract 4.1.1 iOS版をダウンロード",[14,90,91,92,95],{},"(これはiOS向けのものはこちらから取得できます。 ",[27,93,29],{"href":29,"rel":94},[31],")",[14,97,98],{},[27,99,100],{"href":100,"rel":101},"https:\u002F\u002Fgithub.com\u002Fkang298\u002FTesseract-builds-for-iOS\u002Ftree\u002Ftesseract-4.1.1",[31],[14,103,104],{},"ダウンロードして解凍をすると“include”と“lib”の2つのフォルダができます。これらのフォルダをxcodeのプロジェクトの配下へドラッグアンドドロップを行います。",[75,106],{"className":107,"alt":81,"src":108,"style":109},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06172953\u002FScreen-Shot-2020-01-13-at-2.39.35-PM.png","width: 60%;",[85,111,113],{"id":112},"opencv-ios-frameworkのダウンロード","OpenCV iOS frameworkのダウンロード",[14,115,116,120],{},[27,117,118],{"href":118,"rel":119},"https:\u002F\u002Fopencv.org\u002Freleases\u002F",[31]," ダウンロード後xcodeにドラッグアンドドロップを行います。",[75,122],{"className":123,"alt":81,"src":124,"style":109},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06173010\u002FScreen-Shot-2020-01-13-at-1.19.07-PM.png",[14,126,127],{},"エラーがないことを確かめた後、command + Rを押下しBuildしてください。",[85,129,131],{"id":130},"download-languages-trained-model-files","Download languages' trained model files",[14,133,134],{},[27,135,39],{"href":39,"rel":136},[31],[14,138,139,140,143],{},"今回のチュートリアルでは３つの言語、英語、日本語、ベトナム語でテストを行います。そのため私たちはモデルファイルをダウンロードし、",[17,141,142],{},"tessdata","のフォルダを保存しなければなりません。:",[49,145,146,149,152],{},[52,147,148],{},"eng.traineddata",[52,150,151],{},"jpn.traineddata",[52,153,154],{},"vie.traineddata",[14,156,157],{},"xcodeプロジェクトにこれらのフォルダを移動させます。 NOTE: プロジェクトにフォルダを追加する時は\"Create Group\"の代わりに\"Create folder references\"を選択してください。",[75,159],{"className":160,"alt":81,"src":161,"style":83},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06173027\u002FScreen-Shot-2020-01-13-at-3.58.09-PM-1024x299.png",[10,163,165],{"id":164},"coding","Coding",[14,167,168],{},"TesseractはC++で開発しています。そのためC++でのみコーディングができます。tesseract_wrapper.cppの名前でC++ファイルをプロジェクト内に作成してください。以下のような形です。",[75,170],{"className":171,"alt":81,"src":172,"style":83},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06173100\u002FScreen-Shot-2020-01-13-at-2.44.03-PM-1024x740.png",[75,174],{"className":175,"alt":81,"src":176,"style":83},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06173117\u002FScreen-Shot-2020-01-13-at-2.44.09-PM-1024x379.png",[14,178,179],{},"忘れずに“Also create a header file”にチェックをしてください。そうすればC++のヘッダーファイル((tesseract_wrapper.hpp))と共にC++のファイルが出来上がります。",[14,181,182],{},"tesseract_wrapper.hpp",[184,185,190],"pre",{"className":186,"code":188,"language":189},[187],"language-text","\u002F\u002F\n\u002F\u002F  tesseract_wrapper.hpp\n\u002F\u002F  TestTesseract\n\u002F\u002F\n\u002F\u002F  Created by Briswell on 1\u002F13\u002F20.\n\u002F\u002F  Copyright © 2020 Briswell. All rights reserved.\n\u002F\u002F\n\n#ifndef tesseract_wrapper_hpp\n#define tesseract_wrapper_hpp\n\n#include \"opencv2\u002Fimgproc.hpp\"\n#include \"stdio.h\"\n\nusing namespace cv;\nString ocrUsingTesseractCPP(String image_path,String data_path,String language);\n\n#endif \u002F* tesseract_wrapper_hpp *\u002F\n\n","text",[191,192,188],"code",{"__ignoreMap":81},[14,194,195],{},"tesseract_wrapper.cpp",[184,197,200],{"className":198,"code":199,"language":189},[187],"\u002F\u002F\n\u002F\u002F  tesseract_wrapper.cpp\n\u002F\u002F  TestTesseract\n\u002F\u002F\n\u002F\u002F  Created by Briswell on 1\u002F13\u002F20.\n\u002F\u002F  Copyright © 2020 Briswell. All rights reserved.\n\u002F\u002F\n\n#include \"allheaders.h\"\n#include \"opencv2\u002Fimgproc.hpp\"\n#include \"opencv2\u002Fhighgui.hpp\"\n#include \"baseapi.h\"\n#include \"tesseract_wrapper.hpp\"\n\nusing namespace cv;\nusing namespace tesseract;\n\n\u002F*\n matToPix():\n    convert from OpenCV Image Container to Leptonica's Pix Struct\n Params:\n    mat: OpenCV Mat image Container\n Output\n    Leptonica's Pix Struct\n *\u002F\nPix* matToPix(Mat *mat){\n    int image_depth = 8;\n    \u002F\u002Fcreate a Leptonica's Pix Struct with width, height of OpenCV Image Container\n    Pix *pixd = pixCreate(mat->size().width, mat->size().height, image_depth);\n    for(int y=0; yrows; y++) {\n        for(int x=0; xcols; x++) {\n            pixSetPixel(pixd, x, y, (l_uint32) mat->at(y,x));\n        }\n    }\n    return pixd;\n}\n\n\u002F*\n ocrUsingTesseractCPP():\n    Using Tesseract engine to read text from image\n Params:\n    image_path: path to image\n    data_path: path to folder containing .traineddata files\n    language: expeted language to detect (eng,jpn,..)\n Output:\n    String detected from image\n *\u002F\nString ocrUsingTesseractCPP(String image_path,String data_path,String language){\n    \u002F\u002Fload a Mat Image Container from image's path and gray scale mode\n    Mat image = imread(image_path,IMREAD_GRAYSCALE);\n    TessBaseAPI* tessEngine = new TessBaseAPI();\n    \u002F\u002FTesseract 4 adds a new neural net (LSTM) based OCR engine which is focused on line recognition, but also still supports the legacy Tesseract OCR engine of Tesseract 3 which works by recognizing character patterns, in this tutorial we just focus on LSTM only\n    OcrEngineMode mode = tesseract::OEM_LSTM_ONLY;\n    \n    \u002F\u002Finit Tesseract engine\n    tessEngine->Init(data_path.c_str(), language.c_str(), mode);\n    \n    \u002F\u002FSet mode for page layout analysis, refer for all modes supporting\n    \u002F\u002Fhttps:\u002F\u002Ftesseract.patagames.com\u002Fhelp\u002Fhtml\u002FT_Patagames_Ocr_Enums_PageSegMode.htm\n    PageSegMode pageSegMode = tesseract::PSM_SINGLE_BLOCK;\n    tessEngine->SetPageSegMode(pageSegMode);\n    \n    \u002F\u002Fincrease accuracy for japanese\n    if(language.compare(\"jpn\") == 0){\n        tessEngine->SetVariable(\"chop_enable\", \"true\");\n        tessEngine->SetVariable(\"use_new_state_cost\", \"false\");\n        tessEngine->SetVariable(\"segment_segcost_rating\", \"false\");\n        tessEngine->SetVariable(\"enable_new_segsearch\", \"0\");\n        tessEngine->SetVariable(\"language_model_ngram_on\", \"0\");\n        tessEngine->SetVariable(\"textord_force_make_prop_words\", \"false\");\n        tessEngine->SetVariable(\"edges_max_children_per_outline\", \"40\");\n    }\n    \n    \n    \u002F\u002Fconvert from OpenCV Image Container to Leptonica's Pix Struct\n    Pix *pixImage = matToPix(&image);\n    \u002F\u002Fset Leptonica's Pix Struct to Tesseract engine\n    tessEngine->SetImage(pixImage);\n    \n    \u002F\u002Fget recognized text in UTF8 encoding\n    char *text = tessEngine->GetUTF8Text();\n    \n    \u002F\u002Frelease Tesseract's cache\n    tessEngine->End();\n    pixDestroy(&pixImage);\n    \n    return text;\n}\n",[191,201,199],{"__ignoreMap":81},[14,203,204],{},"SwiftはC++を直接呼ぶことができないためこれらのプログラムをobjective-cのwropperファイルを使用します。",[49,206,207,210],{},[52,208,209],{},"TesseractWrapper.h",[52,211,212],{},"TesseractWrapper.mm (not .m because this file is for C++ compilation)",[14,214,209],{},[184,216,219],{"className":217,"code":218,"language":189},[187],"\u002F\u002F\n\u002F\u002F  TesseractWrapper.h\n\u002F\u002F  TestTesseract\n\u002F\u002F\n\u002F\u002F  Created by Briswell on 1\u002F13\u002F20.\n\u002F\u002F  Copyright © 2020 Briswell. All rights reserved.\n\u002F\u002F\n\n#import \"Foundation\u002FFoundation.h\"\n#import \"UIKit\u002FUIKit.h\"\n@interface TesseractWrapper : NSObject\n+(NSString*)ocrUsingTesseractObjectiveC:(UIImage*)image language:(NSString*)language;\n@end\n",[191,220,218],{"__ignoreMap":81},[14,222,223],{},"TesseractWrapper.mm",[184,225,228],{"className":226,"code":227,"language":189},[187],"\u002F\u002F\n\u002F\u002F  TesseractWrapper.m\n\u002F\u002F  TestTesseract\n\u002F\u002F\n\u002F\u002F  Created by Briswell on 1\u002F13\u002F20.\n\u002F\u002F  Copyright © 2020 Briswell. All rights reserved.\n\u002F\u002F\n\n#import \"TesseractWrapper.h\"\n\n#include \"tesseract_wrapper.hpp\"\n@implementation TesseractWrapper\n\n\u002F*\nocrUsingTesseractObjectiveC()\n    call ocrUsingTesseractCPP() to recognize  text from image\n params:\n    image: image to recognize text\n    language: eng\u002Fjpn\u002Fvie\n output:\n    recognized string\n *\u002F\n+(NSString*)ocrUsingTesseractObjectiveC:(UIImage*)image language:(NSString*)language{\n    \u002F\u002Fget path of folder containing .traineddata files\n    NSString* data_path = [NSString stringWithFormat:@\"%@\u002Ftessdata\u002F\",[[NSBundle mainBundle] bundlePath]];\n    \u002F\u002Fsave image to app's cache directory\n    NSString* cache_dir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];\n    NSString* image_path = [NSString stringWithFormat:@\"%@\u002Fimage.jpeg\",cache_dir];\n    NSData* data = UIImageJPEGRepresentation(image, 0.5);\n    NSURL* url = [NSURL fileURLWithPath:image_path];\n    [data writeToURL:url atomically:true];\n    \n    \u002F\u002Fget text from image using ocrUsingTesseractCPP() from file tesseract_wrapper.hpp\n    String str = ocrUsingTesseractCPP([image_path UTF8String], [data_path UTF8String], [language UTF8String]);\n    NSString* result_string = [NSString stringWithCString:str.c_str()\n    encoding:NSUTF8StringEncoding];\n    \u002F\u002Fremove cached image\n    [[NSFileManager defaultManager] removeItemAtURL:url error:nil];\n    return result_string;\n}\n@end\n",[191,229,227],{"__ignoreMap":81},[14,231,232],{},"\"ViewController.swift\"にTextViewとボタンのシンプルな画面を作ります。",[75,234],{"className":235,"alt":81,"src":236,"style":109},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06173139\u002FIMG_8597.png",[14,238,239],{},"ViewController.swift",[184,241,244],{"className":242,"code":243,"language":189},[187],"\u002F\u002F\n\u002F\u002F  ViewController.swift\n\u002F\u002F  TestTesseract\n\u002F\u002F\n\u002F\u002F  Created by Briswell on 1\u002F13\u002F20.\n\u002F\u002F  Copyright © 2020 Briswell. All rights reserved.\n\u002F\u002F\n\nimport UIKit\nimport CropViewController\n\nclass ViewController: UIViewController {\n\n    @IBOutlet weak var txt: UITextView!\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \u002F\u002F Do any additional setup after loading the view.\n    }\n\n    @IBAction func ocr(_ sender: Any) {\n        \u002F\u002Fif camera not supported\n        if !UIImagePickerController.isSourceTypeAvailable(.camera){\n            return\n        }\n        \u002F\u002Fpresent camera to take image\n        let pickerController = UIImagePickerController()\n        pickerController.delegate = self as UIImagePickerControllerDelegate & UINavigationControllerDelegate\n        pickerController.sourceType = .camera\n        self.present(pickerController, animated: true, completion: nil)\n    }\n    \n}\n\nextension ViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{\n    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {\n        picker.dismiss(animated: true) {\n            guard let image = info[.originalImage] as? UIImage else { return  }\n            \u002F\u002Fpresent a crop image frame to focus on text content\n            let cropViewController = CropViewController.init(image: image)\n            cropViewController.delegate = self\n            self.present(cropViewController, animated: true, completion: nil)\n        }\n    }\n\n    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {\n        picker.dismiss(animated: true, completion: nil)\n    }\n}\n\nextension ViewController:CropViewControllerDelegate{\n    func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {\n            cropViewController.dismiss(animated: true) {\n                \u002F\u002Fcall objective-c wrapper with expected language\n                let str = TesseractWrapper.ocr(usingTesseract: image, language: \"jpn\")\n                self.txt.text = str\n            }\n        }\n        \n        func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {            \n            cropViewController.dismiss(animated: true, completion: nil)            \n        }\n}\n",[191,245,243],{"__ignoreMap":81},[14,247,248],{},"これは日本語でのテスト結果です。上記の方法を行えば英語やベトナム語でも確認ができます。",[75,250],{"className":251,"alt":81,"src":252,"style":83},[78,79,80],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06173202\u002FIMG_8598-copy.png",[10,254,255],{"id":255},"最後に",[14,257,258],{},"画像の文字認識は実現可能ですがいくつかの難しいところがあります。 一番は画像の品質（文字サイズ、光、コントラスト）です。それぞれの画像は認証を行う上で認証しにくい様々な問題があります。そのため画像にフィルターを手動でかけて問題を解決するようなオプションもあります。画像品質を改善するために下記のリンクを参照してください。",[14,260,261],{},[27,262,263],{"href":263,"rel":264},"https:\u002F\u002Fgithub.com\u002Ftesseract-ocr\u002Ftesseract\u002Fwiki\u002FImproveQuality",[31],{"title":81,"searchDepth":266,"depth":266,"links":267},2,[268,269,270,271,272],{"id":12,"depth":266,"text":12},{"id":47,"depth":266,"text":47},{"id":69,"depth":266,"text":70},{"id":164,"depth":266,"text":165},{"id":255,"depth":266,"text":255},[274,275],"tech talk","mobile","Briswell Vietnam Co Ltd","2020-01-17","最初にTesseractは様々なオペレーティングシステムで動作する\"optical character recognition(光学式文字認識)\"エンジンです。これはフリーソフトウェアでApacheライセンスの元提供されております。そしてGoogleが2006年から2020年現在までスポンサーとなってます。これは最もポピュラーで最も正確なOCRライブラリです。テキスト検索や画像認識のための人工知能(AI)として利用されます。 これは様々なプラットフォームをサポートしています。MacOS, Window, LinuxだけでなくiOS and Androidも含まれます。 ","md",{},true,"\u002Fja\u002Fnews\u002Ftesseract-ios",null,{"title":5,"description":278},"ja\u002Fnews\u002Ftesseract-ios","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2020\u002F01\u002F06172902\u002Ftesseract.png","cq7a43WvnG12FTKDZ9fBG20NMi_YxXci4tYAuZ_aYYQ",1785320533445]