35
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS Lambda上でOCRして文字の位置を特定したい人生だった。

Posted at

やりたいこと

  • OCRを使って文字の位置を検出したい
  • そんなに頻繁に使うものじゃないからLambdaで動かしたい
  • Webから使いたい

というわけで、できましたー

文字位置特定 with OCR on AWS Lambda

リポジトリはこちら

tesseractってなに?

  • OCRを行ってくれるソフトウェア
  • Macにはbrewで入る(v3.04)
  • 文字を取得するだけじゃなくて文字の位置をhOCR(html)やtsv形式で出力できる <- 重要

どうやってLambdaで動かすの?

  • StackOverflowを参考に...
  • Lambdaではスタンドアローンなバイナリファイルや.soをちゃんと耳そろえてアップすれば動く
  • subprocess(Pythonのコマンドライン実行ライブラリ)も動く

つまり...!!
tesseractと一緒にアップすればLambdaでOCRが動く!!

ちなみに、AmazonLinux上でビルドしないとPillow(PIL)がELF headerがないとかいう妖精さんの首がもげる現象に立ち会い無事死ねます。

文字列の位置どうやって検出するの?

  • 一般的なOCRでは文字をテキストで返してくれることがほとんど
  • Docを読むとv3.05ではtsv形式がサポートされてるくさい
  • 普通にインスコするとtesseract(v3.04)が入っちゃう
  • v3.05を使うべくStackOverflowのとおりに手でビルドしないといけない

これはつらかった。

というわけでいい加減、どうやって導入したかかきます。

# インストール

全部ec2-userでいいです。

必要なパッケージのインストール

sudo yum install -y gcc gcc-c++ make
sudo yum install -y autoconf aclocal automake
sudo yum install -y libtool
sudo yum install -y libjpeg-devel libpng-devel libtiff-devel zlib-devel
sudo yum install -y git

nvmのインストール

AmazonLinuxではyumでいれたnodeのバージョンが古すぎて色々(後述)つらいのでnvmいれておきます。
とはいえAmazonLinuxじゃないとビルドしたところでLambdaでエラーはいてしまうので頑張りましょう。

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
$ source ~/.bashrc 

$ nvm install v6.9.4  
$ nvm alias default v6.9.4  

# バージョンを確認
$ npm -v
$ node -v

Leptonicaのインストール

Leptonica is 画像解析とかやってくれるOSSでtesseract動かすのに必要
ここのバージョンをあげないとtesseractのv3.05も使えない

$ cd ~
$ mkdir leptonica
$ cd leptonica

$ wget http://www.leptonica.com/source/leptonica-1.74.tar.gz

# unzip
$ tar -zxvf leptonica-1.73.tar.gz
$ cd leptonica-1.73

# build
$ ./configure
$ make
$ sudo make install

Tesseractのインストール

まだv3.05はdevなのでリリースに乗ってない == zipが落ちてないのでcloneして頑張ります。

$ cd ~
$ git clone https://github.com/tesseract-ocr/tesseract.git
$ cd tesseract/
$ git checkout -b 3.05 origin/3.05

# initialize
$ ./autogen.sh

# build
$ ./configure
$ make
$ sudo make install

Lambda用にパッケージング

$ cd ~
$ mkdir package
$ cd package

# Copy libraries
$ cp /usr/local/bin/tesseract .
$ mkdir lib
$ cd lib
$ cp /usr/local/lib/libtesseract.so.3 .
$ cp /usr/local/lib/liblept.so.5 .
$ cp /lib64/librt.so.1 .
$ cp /lib64/libz.so.1 .
$ cp /usr/lib64/libpng12.so.0 .
$ cp /usr/lib64/libjpeg.so.62 .
$ cp /usr/lib64/libtiff.so.5 .
$ cp /lib64/libpthread.so.0 .
$ cp /usr/lib64/libstdc++.so.6 .
$ cp /lib64/libm.so.6 .
$ cp /lib64/libgcc_s.so.1 .
$ cp /lib64/libc.so.6 .
$ cp /lib64/ld-linux-x86-64.so.2 .
$ cp /usr/lib64/libjbig.so.2.0 .

# Get trained data
$ cd ..
$ mkdir tessdata
$ cd tessdata
$ wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata
$ wget https://github.com/tesseract-ocr/tessdata/raw/master/osd.traineddata

# Make config file
$ mkdir configs
$ echo 'tessedit_create_tsv 1' > tsv

$ cd ../..
$ zip -r package.zip package

これでLambdaのパッケージに package を閉じ込めてあげると使えるようになります!

やってみた結果wwwwww

草すみませんでした。

image.png

こんな画像をあげた結果がこれ

level	page_num	block_num	par_num	line_num	word_num	left	top	width	height	conf	text
1	1	0	0	0	0	0	0	1080	1920	-1	
2	1	1	0	0	0	29	11	1025	50	-1	
3	1	1	1	0	0	29	11	1025	50	-1	
4	1	1	1	1	0	29	11	1025	50	-1	
5	1	1	1	1	1	29	11	548	50	60	GnAflQflAA
5	1	1	1	1	2	640	15	167	43	58	X-IIZII"
5	1	1	1	1	3	899	14	155	44	89	l11:57
2	1	2	0	0	0	0	0	1080	76	-1	
3	1	2	1	0	0	0	0	1080	76	-1	
4	1	2	1	1	0	0	0	1080	76	-1	
5	1	2	1	1	1	0	0	1080	76	95	 
2	1	3	0	0	0	192	829	197	66	-1	
3	1	3	1	0	0	192	829	197	66	-1	
4	1	3	1	1	0	192	829	197	66	-1	
5	1	3	1	1	1	192	851	93	44	87	00
5	1	3	1	1	2	336	829	53	66	71	la
2	1	4	0	0	0	122	992	718	109	-1	
3	1	4	1	0	0	122	992	718	109	-1	
4	1	4	1	1	0	122	992	718	47	-1	
5	1	4	1	1	1	122	995	88	44	89	Sign
5	1	4	1	1	2	229	995	31	34	94	in
5	1	4	1	1	3	276	997	40	32	86	to
5	1	4	1	1	4	332	997	64	42	89	get
5	1	4	1	1	5	410	993	66	36	86	the
5	1	4	1	1	6	493	997	104	32	84	most
5	1	4	1	1	7	613	997	66	32	86	out
5	1	4	1	1	8	695	992	41	37	91	of
5	1	4	1	1	9	749	1003	91	36	93	your
4	1	4	1	2	0	122	1065	144	36	-1	
5	1	4	1	2	1	122	1065	144	36	87	device.
2	1	5	0	0	0	124	1269	312	46	-1	
3	1	5	1	0	0	124	1269	312	46	-1	
4	1	5	1	1	0	124	1269	312	46	-1	
5	1	5	1	1	1	124	1269	111	36	87	Email
5	1	5	1	1	2	253	1279	40	26	92	or
5	1	5	1	1	3	310	1269	126	46	89	phone

ソースはこんなん

import requirements

from PIL import Image
import sys
import pyocr
import pyocr.builders

import urllib
import os
import subprocess
import base64
import json
import boto3

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
LIB_DIR = os.path.join(SCRIPT_DIR, 'lib')
LANG_DIR = os.path.join(SCRIPT_DIR, 'tessdata')

def response(code, body):
    return {
        'statusCode': code,
        'headers': {
            'Access-Control-Allow-Origin': '*',
        },
        'body': json.dumps(body),
    }

def handler(event, context):
    # Get the bucket and object from the event
    try:
        tools = pyocr.get_available_tools()
        if len(tools) == 0:
            print("No OCR tool found")
            sys.exit(1)
        tool = tools[0]
        print("Will use tool '%s'" % (tool.get_name()))

        request = event['body']

        result_filepath = '/tmp/result'
        img_filepath = '/tmp/image.png'
        with open(img_filepath, 'wb') as fh:
            fh.write(base64.decodestring(request['template']))

        command = 'LD_LIBRARY={} TESSDATA_PREFIX={} {}/tesseract {} {} -l eng --oem 0  tsv'.format(
            LIB_DIR,
            SCRIPT_DIR,
            SCRIPT_DIR,
            img_filepath,
            result_filepath
        )
        print command

        try:
            output = subprocess.check_output(
                command,
                shell=True,
                stderr=subprocess.STDOUT
            )
            print(output)

            with open(result_filepath + '.tsv', 'rb') as fh:
                print(fh.read())
        except subprocess.CalledProcessError as e:
            return "except:: " + e.output

    except Exception as e:
        print(e)
        raise e

あとはGitHub上のserverless.ymlなり何なりを書き換えてご自由にお使いくださいませー。

35
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?