技術雑記帳兼日記帳

AWS、Python、Terraformの使い方をコッソリ

python Amazon Rekognition Detect Text

はじめに

今回は画像からテキストを分析するDetect Textを使ってみる。

準備

下記のプログラムを用意する。

  • detect_text.py.py
from PIL import Image, ImageDraw, ImageFont
import boto3, sys, json, os, traceback

#画像の分析結果を返す
def detect_text(image):
    client=boto3.client('rekognition')
    #写真を読み出して、Byte変換してdetect_faces送信
    file = open(image,'rb')
    response = client.detect_text(Image={'Bytes':file.read()})

    return response

#BoundingBoxを設定する
def set_bounding_box(image, bounding_box_data):
    #画像の高さと幅を取得
    imgWidth, imgHeight = image.size
    draw = ImageDraw.Draw(image)

    #位置を算出
    left = bounding_box_data['Left'] * imgWidth
    top = bounding_box_data['Top'] * imgHeight
    width = bounding_box_data['Width'] * imgWidth
    height = bounding_box_data['Height'] * imgHeight

    points = (
            (left,top),
            (left + width, top),
            (left + width, top + height),
            (left , top + height),
            (left, top)

        )

    draw.line(points, fill='#00d400', width=2)
    
    return

#指定箇所に文字列を設定して返す
def set_bounding_box_text(image, text, bounding_box_data):

    #画像の高さと幅を取得
    imgWidth, imgHeight = image.size
    draw = ImageDraw.Draw(image)

    #位置を算出
    left = bounding_box_data['Left'] * imgWidth
    top = bounding_box_data['Top'] * imgHeight
    width = bounding_box_data['Width'] * imgWidth
    height = bounding_box_data['Height'] * imgHeight

    draw = ImageDraw.Draw(image)
    #フォントの設定
    font_ttf = "/usr/share/fonts/truetype/fonts-japanese-gothic.ttf"
    draw.font = ImageFont.truetype(font_ttf, 25)

    color = (0,255,0)
    pos = (left, top)
    #文字の設定
    draw.text(pos, text, color)
    return

if __name__ == '__main__':
    if len(sys.argv) != 3:
        exit()
    
    in_file_name = sys.argv[1]
    out_file_name = sys.argv[2]

    try:
        #画像分析
        #jsonが無ければ分析あれば使う
        json_file_name = in_file_name + '.json'
        if (os.path.exists(json_file_name) == True):
            file = open(json_file_name, 'r')
            response = file.read()
            response = json.loads(response)
        else:
            response = detect_text(in_file_name)
            file = open(json_file_name, 'w')
            file.write(json.dumps(response))

        #分析元の画像を読み込み
        image = Image.open(in_file_name)
        
        #画像に分析結果の設定
        cnt = 1
        for text in response['TextDetections']:
            #boundingboxを設定
            set_bounding_box(image, text['Geometry']['BoundingBox'])
            set_bounding_box_text(image, str(cnt), text['Geometry']['BoundingBox'])
            print(str(cnt) + ' is ' + 'Type:' + text['Type'] + ' [' + text['DetectedText'] + ']')
            cnt = cnt + 1

        #結果の出力
        image.save(out_file_name)


    except Exception as e:
        print(e)
        print(traceback.format_exc())

実行方法

python detect_text.py 分析したいファイル.jpg 出力したいファイル名.jpg
  • 実行結果
    今回は何枚か画像を貼り付けてみる
    数字がかぶって見づらいけど画像に数字を埋め込んで、ターミナルに数字と文字タイプ、文字列を表示するようにした。


1個めはIRON MAIDENのアルバムジャケット

f:id:halhalhal1:20210503101313j:plain

1 is Type:LINE [IRAN MAAIDEN]
2 is Type:LINE [Kllers]
3 is Type:WORD [IRAN]
4 is Type:WORD [MAAIDEN]
5 is Type:WORD [Kllers]

2個めはNIRVANAのアルバムジャケット
f:id:halhalhal1:20210503101603j:plain

1 is Type:LINE [NIRVANA]
2 is Type:LINE ["BLEACH'']
3 is Type:WORD [NIRVANA]
4 is Type:WORD ["BLEACH'']

3個めはネコは見ている系の寄せ集め
f:id:halhalhal1:20210503101825j:plain

1 is Type:LINE [7IL71]
2 is Type:LINE [HOMLSI]
:
48 is Type:WORD [LT ]
49 is Type:WORD [t]
50 is Type:WORD [OHOEN'OCFLS]
51 is Type:WORD [K]

まとめ

ラストが若干狂気じみているが、これはdetect textが日本語に対応していないからっぽい。
崩し文字は、そのままそれっぽく見えるアルファベットに変換してくれる。
NIRVANA」や「BLEACH」はさすがの検出力。