R&D チームの徳田(@dakuton)です。
過去記事にて紹介したLayoutParserがバージョンアップ(v0.3.0以降)により、EfficientDetによるドキュメントレイアウト解析がサポートされたので動かしてみました。
技術解説
EfficientDetとLayoutParserの技術的な説明については、それぞれ過去記事をご確認ください。
tech-blog.optim.co.jp tech-blog.optim.co.jp
v0.3.0から追加された機能の1つとして、レイアウト解析(物体検出)のマルチバックエンド利用に対応しています。
前回のLayoutParser記事時点(v0.2.0)だとレイアウト解析は下記1のみサポートでしたが、2021/10/07時点で2,3が追加利用可能になっています。
- Detectron2
- EfficientDet(effdet)
- PaddlePaddle
- 3を利用する場合はInstallation記載とは別途
pip install "layoutparser[paddledetection]"
が必要です。
- 3を利用する場合はInstallation記載とは別途
サンプル
テストデータ
前回記事と同様の、夏季インターンシップ募集ページの部分スクリーンショット(コース概要)を使用しました。
(2021年度の募集は締め切りました。多数応募・参加いただきありがとうございます。)
サンプルコード(parse_table_layout.py
)
前回のLayoutParser記事時点(v0.2.0)では、Model Zooの記載に従い、config_path
(利用したいモデル)に応じてlabel_map
を指定する必要がありましたが、マルチバックエンド対応により指定不要(AutoLayoutModel
による自動選択)になりました。
ただし、検出しきい値をデフォルト値以外に変更したい場合はextra_config
での指定方法が利用モデルによって異なる点に注意してください。
import argparse import cv2 import layoutparser as lp def main(): args = parse_args() image = cv2.imread(args.src) """以下と同じ > model = lp.EfficientDetLayoutModel( > 'lp://PubLayNet/tf_efficientdet_d1/config', > extra_config={"output_confidence_threshold": 0.25}, > label_map={1:"Text", 2:"Title", 3:"List", 4:"Table", 5:"Figure"} > ) Model/Config Full Path Formats: lp://<backend-name>/<dataset-name>/<model-architecture-name> https://github.com/Layout-Parser/layout-parser/blob/v0.3.0/src/layoutparser/models/model_config.py#L23 """ model = lp.AutoLayoutModel('lp://efficientdet/PubLayNet/tf_efficientdet_d1') layout = model.detect(image) ocr_agent = lp.GCVAgent.with_credential(args.gcp_credential_json, languages=['ja']) res = ocr_agent.detect(image, return_response=True) ocr_layout = ocr_agent.gather_full_text_annotation(res, agg_level=lp.GCVFeatureType.BLOCK) print('### レイアウト解析なし') print('\n'.join(ocr_layout.get_texts()).replace(' ', '')) print('### レイアウト解析あり(図表エリアごとにテキスト抽出)') for l in detectron2_layout: if l.type in ['Table' ,'Figure']: texts = ocr_layout.filter_by(l.block, center=True).get_texts() print('\n'.join(texts).replace(' ', '')) def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--gcp_credential_json', type=str) parser.add_argument('--src', type=str) args = parser.parse_args() return args if __name__ == '__main__': main()
元画像
解析結果
OCRとレイアウトそれぞれの検出位置を可視化してみたところ、今回用いたサンプルデータについては、残念ながらEfficientDetよりも前回利用したMask R-CNN(Detectron2)のほうが適切にレイアウト分離できています。
- 赤枠: OCR(Google Cloud Vision ブロック検出)
- 青色透過: ドキュメントレイアウト(Detectron2またはEfficientDet)
Detectron2(mask_rcnn_X_101_32x8d_FPN_3x)
EfficientDet(tf_efficientdet_d1)
所感
前回のLayoutParser記事(LayoutParserを利用するメリット・デメリットは?)にてメリットとして述べた「OCR部分とレイアウト解析部分のモジュール分離による再利用性向上」が、実際にバージョンアップにより強化されている点は好感が持てます。
利用方法のドキュメント更新についてはまだ追いついていない部分もありますが、1行(AutoLayoutModel
で指定するモデル)変更で試せるようになったので、今後のアップデートに期待です。
オプティムでは技術をいい感じに使ってデジタライゼーションに貢献できるエンジニアを募集しています。