Google Apps Script とGoogleドライブでOCR

おそらくこちらの記事にたどりついた方は、Google Apps Scriptを使ってお手軽にOCRしてテキスト文字化をする事に興味をお持ちの方が多いのだと思います。
こちらの記事ではローカルPCの実行環境を利用して画像形式のファイルからテキスト情報を得る方法を調査しました。
無償で構築できる環境としては魅力もありOCRの精度としてもかなり期待できるのですが、お手軽に始める事ができるかと、と言うと、開発環境の導入を考えるとそれほど簡単でお手軽とは分類できませんでした。
また、様々な業務用ファイルを全文検索する元データを準備する必要もあり、様々なファイル形式からテキストデータに変換するDOC2TXT的な変換方法を検討する中で、Google Apps Script とGoogleドライブの組み合わせでテキスト化する自動処理に有効な可能性を感じたので、サンプルを構築して、その精度を確認してみる事にしました。

Googleが無償の範囲で使わせてくれるサービスとしては、Googleドライブ上で利用できるドキュメントサービス、そのマクロ機能とも言える、Google Apps Scriptが鬼に金棒と言える位の便利さとして有名なところです。

Google Apps Script に関しては、様々なインターネット記事がありますので、それらの記事を参考にして次のような処理を実現してみました。

  1. Googleドライブの所定のフォルダを定期的に監視する
  2. 監視フォルダ中に何らかのファイルが保管されたら、そのファイルをGoogle Appsドキュメントで開き、テキスト化して別のフォルダに.txt、.pdfの拡張子付の同名ファイルで保管する
  3. OCRを終えた原本ファイルは所定のフォルダに移動する

この処理で言う、「フォルダ」とは、Googleドライブ上に存在するフォルダですので、WindowsOSから直接アクセスするためには、Googleアカウントとドライブ同期などによる設定が必要ですが、PC上に開発環境や、tesseract(テッセラクト)の環境を整える必要がありませんから、比較的お手軽です。

スマートフォンのカメラアプリで撮影してドライブの当該ディレクトリにアップロードしてみます。下図のIMG_4635.JPGがそれです。

このフォルダを先に準備した処理で定期的に処理するようにScriptの時間トリガーを設定あるので、フォルダ直下のファイルはOCR処理を実行し、正常に処理を終えると処理済フォルダに移動され、OCR結果のtxtとPDFフォルダに新規作成します。

こちらが実データ

Google Apps ドキュメントで開けるファイル形式はOffice形式ファイルを含めて多くあるため、DOC2TXTのような結果を得るのも簡単ですが、クラウド上処理時間が無償処理の範囲で完結するように工夫も必要になります。

 function myFunction() {
  var PrjDirId = プロジェクトのTOPフォルダのID;
  var Doc2PdfDirId = 定期監視対象のフォルダのID;
  var PdfDirId = 生成したテキストファイルの保管先フォルダID;
  var DoneDirId = 処理済ファイル保管先フォルダID;
  var LogFileId = 処理記録用スプレッドシートドキュメントのID;
  
  var Doc2PdfDir = DriveApp.getFolderById(Doc2PdfDirId);
  var PdfDir = DriveApp.getFolderById(PdfDirId);
  var DoneDir = DriveApp.getFolderById(DoneDirId);
  var spsheet  = SpreadsheetApp.openById(LogFileId);
  var sheet = spsheet.getActiveSheet();
  
  //対象のフォルダ内に存在するファイルを検出する
  var files = Doc2PdfDir.getFiles();

  //検出したファイルを逐一処理する
  while(files.hasNext()){
    var FileInfoText = [];
    var doc = files.next();
    var DocFileId=doc.getId()
    var docName = doc.getName().split("\.")[0];
    var createDateRaw = doc.getDateCreated();
    var createDate = Utilities.formatDate(createDateRaw,"JST","YYYY/MM/dd HH:mm");
    var NowYMDHMS = Utilities.formatDate(new Date(), "JST", "yyyyMMdd_hhmmss")
    //Googleドキュメントを生成する処理
    var Request_body = {
      title: docName, 
      mimeType: 'image/jpeg', 
      "parents":  [{"id": Doc2PdfDirId}]
    }
    var newFile = Drive.Files.insert(Request_body, doc, { ocr: true });
    var docId = newFile.getId();
    var doc = DocumentApp.openById(docId);
    var text = doc.getBody().getText()
    //スペース文字を削除
    var text = text.replace(' ','')
    var text = text.replace(' ','')
    //ファイル情報記録用文字列の準備とpdfファイルの生成
    FileInfoText.push([NowYMDHMS,docId, createDate, docName, text]);
    var docPDF = doc.getAs('application/pdf').setName(NowYMDHMS + '_' + docName +'.pdf');
    PdfDir.createFile(docPDF);
    
    //TXTを保管する
    var docTXT = doc.getBody().getText();
    PdfDir.createFile(NowYMDHMS + '_' + docName + '.txt', docTXT);
    doc.saveAndClose();  //閉じる・・・いらないかも
    
    //一時生成したドキュメントの削除
    Doc2PdfDir.removeFile(DriveApp.getFileById(docId));
    
    //オリジナルファイルを処理済みフォルダに移動
    DoneDir.addFile(DriveApp.getFileById(DocFileId));
    Doc2PdfDir.removeFile(DriveApp.getFileById(DocFileId));
    
    //処理したファイルがあれば記録を残す
    if (FileInfoText.length!=0) {
      var AValues = sheet.getRange('A:A').getValues();  
      var lr = AValues.filter(String).length;
      sheet.getRange(lr+1, 1, FileInfoText.length, FileInfoText[0].length).setValues(FileInfoText);
      var range = sheet.getDataRange()
      range.sort({column: 1, ascending: false});
    }    
  }
}

上記コードを実行するには、DriveAPIを有効にする必要があります。

感想

写真ファイル(jpg,png)からのOCR結果を様々観察してみましたが、tesseract(テッセラクト)では厳しい画像でも、さすがGoogleのVISIONエンジン、斜めからの映像でも、 記事上の画像のように ランドスケープ、ポートレートに関係なく、「読みとれる」状態に回転したうえでテキスト化してくれます。
また、Office形式のファイル(doc,docx,xls,xlsx,ppt,pptx・・・)もGoogleドキュメントととして開くことができれば、画像ファイルと同様に処理できます。

処理するファイルの複雑さによっては、Googleドキュメントで開く処理にそれなりの時間が掛かりますので、Google Apps Scriptの実行時間上限(無償アカウントだと5分程度)を超えてしまう事もあり得ます。
従って、大量にファイルが投入されるフォルダを監視するような処理は実用的ではありませんし、While loop の 構造と、トリガーの時間設定を工夫する必要もあります。
時間が掛かっても問題ない、非同期でtxtファイルが準備できれば十分な用途であれば応用できるかもしれませんので参考にしてみてください。
いつまで無償でこのような環境を利用できるのかはGoogleの戦略次第とは思いますが、一時的に必要なデータをクラウドのリソースを使って自動処理できるとは、すごく便利だと思います。LINEのBOTと組み合わせてみたりとか、独自に利用できる幅は広いと思いました。

参考にしたサイト

  • http://www.initialsite.com/g07/16371
  • https://www.pre-practice.net/2019/01/ocr.html
  • http://www.googleappsscript.info/2017-12-31/drive_delete_files.html

シェアする

  • このエントリーをはてなブックマークに追加

フォローする