Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CloudVisionAPIでOCRする

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 CloudVisionAPIでOCRする

Avatar for KosukeShimizu

KosukeShimizu

October 03, 2023

More Decks by KosukeShimizu

Other Decks in Programming

Transcript

  1. CloudVisionAPIでOCRする 自己紹介 • Name: 清水 幸佑(Kosuke Shimizu) ◦ thimi0412 •

    Language ◦ Python ◦ Go • Job: 2022-02 WEDにJOIN ◦ データエンジニア ◦ OCR周りの開発 ◦ データ基盤やデータパイプラインの作成 ◦ ML周りのインフラ基盤の作成 3
  2. CloudVisionAPIでOCRする 5 VisionAPIの説明 • 顔検出 • 物体検出 • OCR(文字認識) •

    ランドマーク検出 • etc… https://cloud.google.com/vision/docs/drag-and-drop
  3. CloudVisionAPIでOCRする 6 ONEのOCRについて { "purchased_at": "2020-06-12", "address": null, "items": [

    { "name": "食パン", "quantity": 1, "price": 340 }, { "name": "塩レモン", "quantity": 1, "price": 350 } ], … } APIに画像を POSTしてJSON を取得する
  4. CloudVisionAPIでOCRする • レシートをそれぞれの領域に分ける ◦ header ▪ 店名, 住所, TEL ◦

    item ▪ 商品名, 値段, 個数 ◦ total ▪ 合計金額, 小計 ◦ footer ▪ sumより下部の領域 • おそらくheaderとtotalの部分に商品がある ◦ 商品名の右 or 右下に数字があるものを 商品名として抽出している ◦ 変なものも商品名として取得してしまう ことがある 8 商品名を取得する
  5. CloudVisionAPIでOCRする 10 清水の思考(土日) S • 機械学習のモデルとか組み込む からPythonで書くかぁ • PythonならFastAPIで書くかぁ •

    どうせGKEで動かすから Dockerも必要かぁ • 多分商品名の抽出とかはML チームがやってくれるはず • まずは基盤となる OCR部分だけ作るかぁ
  6. CloudVisionAPIでOCRする 12 API呼び出し部分 from google.cloud import vision def text_detection( content:

    str, vision_api_model: str ) -> vision.AnnotateImageResponse: image = vision.Image(content=content) client = vision.ImageAnnotatorClient(credentials=env.google_credentials) req = vision.AnnotateImageRequest( image=image, features=[ vision.Feature( type=vision.Feature.Type.TEXT_DETECTION, model=vision_api_model ), ], image_context={"language_hints": ["ja", "en"]}, ) response: vision.AnnotateImageResponse = client.annotate_image(req) return response
  7. CloudVisionAPIでOCRする 13 API呼び出し部分 content: str = base64.b64encode(data).decode() response: vision.AnnotateImageResponse =

    text_detection( content, "builtin/latest" ) • open関数でfile.read()したbytesをbase64で変換してデコードすれば使える • builtin/latestはVisionAPIで使用するmodelの名前 ◦ builtin/latest: 最新版 ◦ builtin/stable: 安定版 ◦ builtin/legacy: 古い版 ◦ 以前はbuiltin/stableを使っていたがbuiltin/latestにして 餃子という文字が鮫子と読んでしまう問題が解決した!
  8. CloudVisionAPIでOCRする 15 レスポンスの中身を見てみる { "description": "セブン", "bounding_poly": { "vertices" {

    "x": 920, "y": 131 } "vertices" { "x": 1446, "y": 137 } "vertices" { "x": 1444, "y": 260 } "vertices" { "x": 919, "y": 254 } } } • bounding_poly.verticesに OCRされた文字を囲うx, y座標が格納されてい • 座標の順番は左下から反時計回り
  9. CloudVisionAPIでOCRする 16 レスポンスの中身を見てみる [ "7 セブン-イレブン", "新宿余丁町店", "東京都新宿区余丁町10-10", "電話:03-3351-2122", "2023年09月10日

    (日) 14:48", "領収書", "ダイソーキッチンペーパ-168枚", "ピルクル ミラクルケア", "195ml", "@135x 2", "炭火焼き豚丼", "小 計 (税抜 8%)", "消費税等 (8%)", "小計 (税抜10%)", "消費税等 (10%)", "合計", ... ] レスポンスはBlockという単位で分かれていて y座標でソートされていないので並び替えが必要 後ろのあるはずの 100がない
  10. CloudVisionAPIでOCRする 1. 空のリストを作成 2. 各行の4点のX, Y座標の平均を計算 3. X, Y座標の平均と文字をリストに格納 4.

    Y座標が近いもので1行を作成する a. Y座標の差が15以内だったら 同じ行と判定(勘) (p.s. ChatGPTに教えてもらいました) 17 Y座標で並び替える docs = [] for text in texts: vertices = [ {"x": vertex.x, "y": vertex.y} for vertex in text.bounding_poly.vertices ] # 頂点の座標の平均を取る average_x = sum([vertex["x"] for vertex in vertices]) / len(vertices) average_y = sum([vertex["y"] for vertex in vertices]) / len(vertices) docs.append( {"text": text.description, "vertex": {"x": average_x, "y": average_y}} ) # y座標でデータをソート sorted_data = sorted(docs, key=lambda x: x["vertex"]["y"]) # グループ分け groups = [] current_group = [] for i in range(len(sorted_data) - 1): current_group.append(sorted_data[i]) if ( sorted_data[i + 1]["vertex"]["y"] - sorted_data[i]["vertex"]["y"] > threshold ): groups.append(current_group) current_group = [] # 最後のグループを追加 current_group.append(sorted_data[-1]) groups.append(current_group) セブン ー イレブン 差が15以内
  11. CloudVisionAPIでOCRする • 傾いた画像だとOCRしずらいので画像の傾きを補正する(済) ◦ MLチームの方が作ってくれた(あんまり理解してない) • 固有表現抽出等を使用して商品名などを抽出する ◦ T5(Text-to-Text Transfer

    Transformer) で今いい感じに取れるらしい • レシート画像以外への対応 ◦ 新幹線の切符 ◦ そのほかチケットとか 19 今後やっていきたいこと