MIT App Inventorで画像からテキスト検出（OCR）を行う方法

:::note info
**プログラミングを使用しないで，ブロックのみでテキスト認識を行う方法**
[MIT App Inventorでテキスト認識OCRを行う方法（プログラミング必要無し）](https://qiita.com/aaaxxx___abc/items/c731d3c8696d7f9fedb1)
:::

## はじめに
ここでは，MIT App Inventorでのテキストの検出（OCR）を行います．GoogleのCloud Visionを使用します．
アプリでテキスト検出を行うことができれば，アプリの幅が格段と広がりそうですね！
わからない漢字を調べるアプリや英語の発音をしてくれるアプリなどに応用できそうです．

テキストの検出をCloud Visionで行うが，MIT App Inventorから直接アクセスする方法が見つからなかったため，GoogleのCloud Runを経由してテキスト検出を行います．


## アプリの概要
アプリで写真を撮影し，ボタンをクリックすると文章がCloud Run, Cloud Vision APIを使用して，テキストを検出しレスポンスとして認識したテキストをスクリーンに表示します．

## Cloud Vision API
Cloud Vision APIとは？
>[Cloud Vision API](https://cloud.google.com/vision/docs?hl=ja)
>Cloud Vision API を使用すると、開発するアプリケーションの中で簡単に画像検出機能を統合できます。この機能の例としては、画像ラベリング、顔やランドマークの検出、光学式文字認識（OCR）、露骨な表現を含むコンテンツへのタグ付けがあります。

## Cloud Run
Cloud Runとは？
>[Cloud Run](https://cloud.google.com/run?hl=ja)
>フルマネージドのプラットフォームでアプリやウェブサイトをすばやく構築

## Designer画面
![スクリーンショット 2024-11-22 193156.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/a9a14254-aea0-8973-b0eb-23ea0e6fccc8.jpeg)

| 機能 | 内容 |
|:-:|:-:|
| カメラ  |  ボタン，写真撮影 |
|  テキスト認識 |  ボタン，テキスト認識を行う |
|image1|撮影した画像を表示する|
|Camera1|写真撮影|
|Web1|CloudRunへのアクセス|
|KIO4_Base641|画像をbase64にエンコードする|

:::note info
base64へのエンコードするブロックはExtensionsです．[KIO04 Base64](http://kio4.com/appinventor/277_extension_imagen_string.htm)
:::

## Blocks画面
### 変数
・CloudRunURL
CloudRunへリクエストを送る変数．自身のCloudRunのURLを入れてください．
![blocks (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/d2804b94-b1ed-a3ba-3ebe-e5a5a78b8adc.png)

### ボタンクリック
・カメラ
![blocks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/066fb9f7-65aa-4f01-d58d-73eacba68633.png)

・テキスト認識
![blocks (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/d0780b5f-e110-89f1-d69f-2dc529981890.png)

### When Camera1. After Picture
![blocks (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/330e347c-4482-fcbc-9a65-ef12b151ff36.png)

### when KIO4_Base641. After Image Base64
![blocks (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/3bc79203-02b7-dc36-b029-1b268b4c8940.png)

### when Web1. Got Text
![blocks (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/3f0a8e3a-a156-94a7-1298-faee94d620ac.png)

## コードの記述
Cloud Vision APIを使用できるようにし，Cloud Runにコードを記述します．
生成AIに書いてもらいました～～！AIってほんとに優秀ですね．
```main.py
import base64
import json
from googleapiclient import discovery
from flask import Flask, request, jsonify
import functions_framework

app = Flask(__name__)

# Google Cloud Vision API のエンドポイント
VISION_API_ENDPOINT = "https://vision.googleapis.com/v1/images:annotate"

@app.route('/extract_text', methods=['POST']) # POSTメソッドに変更
def extract_text():
    """Base64エンコードされた画像を取得し、テキストを抽出し、JSONで返す"""
    try:
        # リクエストからBase64エンコードされた画像データを取得
        data = request.get_json()
        base64_image = data.get('image')

        if not base64_image:
            return jsonify({"error": "imageデータがありません"}), 400

        # リクエストの本文（JSON）を作成
        request_body = {
            "requests": [
                {
                    "image": {
                        "content": base64_image
                    },
                    "features": [
                        {
                            "type": "TEXT_DETECTION"
                        }
                    ]
                }
            ]
        }

        # Google Cloud Vision API のクライアントを作成
        service = discovery.build(
            'vision', 'v1', credentials=None,
            cache_discovery=False,  # キャッシュを無効にする
            static_discovery=False  # 静的検出を無効にする
        )

        # リクエストを送信
        response = service.images().annotate(body=request_body).execute()

        # レスポンスを処理
        if response.get('responses'):
            text_annotations = response["responses"][0].get("textAnnotations", [])
            # 全てのテキストをリストに格納
            all_text = []
            for annotation in text_annotations:
                all_text.append(annotation.get('description', '')) # descriptionがなかった場合空文字列を返すように修正

            # 抽出したテキストをJSON形式で返す
            return jsonify({"all_text": all_text[0]}) 

        else:
            return jsonify({"error": f"Vision APIリクエストエラー: {response.status_code}"}), 500

    except Exception as e:
        return jsonify({"error": str(e)}), 500

@functions_framework.http
def main(request):
    """HTTPリクエストを処理する"""
    return extract_text()
```

```requirements.txt
functions-framework==3.*
requests
google-api-python-client
```

## CloudRunからURLを貼り付け
![スクリーンショット 2024-11-22 195316.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3928359/540b8bd3-2d76-676f-bc8e-2c9718879757.jpeg)

## 終わりに
GoogleのCloud Vision APIを使用することでテキスト認識することができた．
テキスト認識をMIT App Inventorで使用することでいろいろなアプリに応用することができますね！