画像をS3へアップロードしたことをきっかけに、Amazon TextractでOCRを実行し、抽出したテキストを別のS3へ保存するサンプルを紹介します。
今回の構成では、AWSのマネージドサービスを組み合わせて、シンプルで堅牢な自動OCRパイプラインを構築します。
💡 処理の流れ(概要)
S3に画像を置く ➔ Lambdaが自動起動 ➔ TextractでOCR実行 ➔ 結果をS3へ保存
今回は、単一ページの画像を対象として、Textractの同期APIである DetectDocumentText を使用します。
アーキテクチャ
[画像アップロード]
│
▼
[S3 Input用バケット]
│
│ オブジェクト作成イベント
▼
[AWS Lambda]
│
│ DetectDocumentText
▼
[Amazon Textract]
│
│ OCR結果
▼
[AWS Lambda]
│
│ テキスト保存
▼
[S3 Output用バケット]
Input用S3に画像をアップロードすると、S3イベントをきっかけにLambdaが起動します。
LambdaからTextractを呼び出してテキストを抽出し、その結果をOutput用S3へ保存します。
1. S3バケットを用意する
OCR対象の画像を保存する Input用S3バケット と、OCR結果を保存する Output用S3バケット を用意します。今回は入力と出力を分けて管理します。
Input用S3
└── OCR対象の画像
Output用S3
└── OCR結果
例えば、Input用S3に以下のように画像をアップロードするとします。
Input用S3
└── images/
└── sample.png
OCR結果はOutput用S3の同階層に以下のように保存されます。
Output用S3
└── extracted/
└── images/
└── sample.txt
2. Lambda関数を作成する
AWS Lambdaで関数を作成します。ランタイムは、今回のサンプルでは Python 3.12 を使用します。
Lambdaには、S3から画像を取得し、TextractでOCRを実行して、結果をS3へ保存する処理を実装します。
IAM権限
Lambdaの実行ロールには、以下の権限を付与します。
| 権限 | 用途 |
|---|---|
| S3:読み取り | Input用S3から画像を取得 |
| S3:書き込み | Output用S3へOCR結果を保存 |
| Textract:DetectDocumentText | OCR処理を実行 |
| CloudWatch Logs | Lambdaの実行ログを出力 |
環境変数
Lambdaの環境変数に、OCR結果を保存するOutput用S3バケット名を設定します。
| キー | 値 |
|---|---|
| OUTPUT_BUCKET_NAME | Output用S3バケット名 |
コード内では、以下のように取得します。
OUTPUT_BUCKET = os.environ.get('OUTPUT_BUCKET_NAME')
3. S3をLambdaのトリガーに設定する
Lambda関数の「トリガーを追加」からS3を選択します。
設定例は以下の通りです。
| 設定項目 | 設定例 |
|---|---|
| 追加対象 | Input用S3 |
| イベントタイプ | すべてのオブジェクト作成イベント |
| プレフィックス | 必要に応じて設定(例: images/) |
| サフィックス | 必要に応じて設定(例: .png) |
これで、Input用S3にファイルがアップロードされると、Lambdaが自動的に起動します。
4. Lambda関数を実装する
以下のPythonコードをLambdaへ設定します。
import json
import os
import urllib.parse
import boto3
s3_client = boto3.client('s3')
textract_client = boto3.client('textract')
# 環境変数から出力バケット名を取得
OUTPUT_BUCKET = os.environ.get('OUTPUT_BUCKET_NAME')
def lambda_handler(event, context):
for record in event['Records']:
# S3イベントからバケット名とオブジェクトキーを取得
input_bucket = record['s3']['bucket']['name']
image_key = urllib.parse.unquote_plus(
record['s3']['object']['key'],
encoding='utf-8'
)
print(
f"Processing image: {image_key} "
f"from bucket: {input_bucket}"
)
try:
# Amazon Textractの呼び出し(同期API)
response = textract_client.detect_document_text(
Document={
'S3Object': {
'Bucket': input_bucket,
'Name': image_key
}
}
)
# LINEブロックからテキストを取得
extracted_lines = []
for block in response.get('Blocks', []):
if block['BlockType'] == 'LINE':
extracted_lines.append(block['Text'])
extracted_text = "\n".join(extracted_lines)
# OCR結果の保存先
output_key = (
f"extracted/"
f"{os.path.splitext(image_key)[0]}.txt"
)
# S3へ保存
s3_client.put_object(
Bucket=OUTPUT_BUCKET,
Key=output_key,
Body=extracted_text.encode('utf-8'),
ContentType='text/plain; charset=utf-8'
)
print(
f"Successfully extracted text to "
f"s3://{OUTPUT_BUCKET}/{output_key}"
)
except Exception as e:
print(
f"Error processing object "
f"{image_key}: {str(e)}"
)
raise
return {
'statusCode': 200,
'body': json.dumps(
'Extraction completed successfully!'
)
}
5. 動作確認
設定が完了したら、Input用S3へ画像をアップロードします。
Input用S3
└── images/
└── sample.png
画像がアップロードされると、S3イベントによってLambdaが自動的に起動します。
LambdaからTextractが実行され、OCR結果がOutput用S3へ保存されます。
Output用S3
└── extracted/
└── images/
└── sample.txt
sample.txt を開いて、画像から抽出されたテキストを確認します。
まとめ
今回のサンプルでは、以下の自動化フローを構築しました。
- S3へ画像をアップロード
- Lambdaが自動起動
- TextractでOCR実行
- OCR結果をS3へ保存
S3・Lambda・Amazon Textractを組み合わせるだけで、画像をS3へ置くことをきっかけにOCR処理を完全自動化できます。
まずはこのような小さな構成から、AWSのOCR処理を試してみてください!
ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。
- 選考ではありません
- 履歴書不要
- 技術の話が中心
- 所要時間30分程度
- オンラインOK