質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

1回答

2243閲覧

AWS Rekognitionの出力結果をjsonファイルに出力し、S3バケットに保存したい。

fusaan

総合スコア0

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2021/10/05 01:59

編集2021/10/05 02:56

お世話になります。
AWSおよび、Python初学者で右も左もわからず困っている状況です…。

実現したいこと

AWS Rekognitionの画像からテキストをOCRする機能(TextDetection)を、AWS Lambdaで使用して、出力結果をJsonファイルに落とし込み、S3に出力結果のJsonファイルを保存しようと試みています。

Rekognitonのマネジメントコンソール上で、手動でテキスト出力した結果のままを、JSONファイルに記載し、S3バケットに保存したいのですが、
現状、抽出されたテキストのみ出力されるされるような結果となっています。

以下のような流れで実現しようとしています。

①S3バケットにjpgファイルを格納
②Lambdaが①のバケットを確認し、jpgファイルがある場合はLambdaが①で格納した
ファイル名を抽出し、file_list.txtを作成。
③Lambdaのtmpに②のfile_list.txtを格納。
④LambdaがRekognitionを呼び出し、file_list.txtに記載されているファイル名をS3から取得。RekognitionでOCRを実施する。
⑤出力結果をJsonファイルに記載し、s3バケットにアップロード。

実際にS3バケットに格納された出力結果は、下記のようになっております。

JSON

1Detected text:THEMENT 2Detected text:XKR

実現したいこと

上記のような結果ではなく、最終的にマネジメントコンソールで手動でRekognitionを実施したそのままの結果の形で、出力された結果を、JSONファイルでS3に保存したいと考えております。下記のような形式となります。
解決策をご教示いただけないでしょうか。
よろしくお願いいたします。

JSON

1{ 2 "TextDetections": [ 3 { 4 "Confidence": number, 5 "DetectedText": "string", 6 "Geometry": { 7 "BoundingBox": { 8 "Height": number, 9 "Left": number, 10 "Top": number, 11 "Width": number 12 }, 13 "Polygon": [ 14 { 15 "X": number, 16 "Y": number 17 } 18 ] 19 }, 20 "Id": number, 21 "ParentId": number, 22 "Type": "string" 23 } 24 ], 25 "TextModelVersion": "string" 26}

試したこと

実装したコードは下記のとおりです。

JSON

1from __future__ import print_function 2import json 3import boto3 4import os 5import urllib 6from boto3 import Session 7 8 9print('Loading function') 10 11 12# バケット名,オブジェクト名 13BUCKET_NAME = 'S3バケットの名称' 14S3KeyPrefix = 'S3のjpegファイルが格納されたフォルダ名' 15 16s3 = boto3.resource('s3') 17bucket = s3.Bucket(BUCKET_NAME) 18objs = bucket.meta.client.list_objects_v2(Bucket=bucket.name, Prefix=S3KeyPrefix) 19 20def lambda_handler(event, context): 21 22 # S3のファイルをテキストに出力 23 text = '' 24 for o in objs.get('Contents'): 25 key = o.get('Key') 26 if key[-4:]=='.jpg': 27 text += '{}\n'.format(key) 28 29 s3.Object(BUCKET_NAME, S3KeyPrefix + 'file_list.txt').put(Body=text) 30 31 # tmpにfile_list.txtを格納 32 bucket.download_file(S3KeyPrefix + 'file_list.txt', '/tmp/file_list.txt') 33 34 # file_list.txtを開き、一行ずつ読み取る 35 fileobj = open("/tmp/file_list.txt", "r", encoding="utf_8") 36 line = fileobj.readline() 37 38 # Rekognition呼び出し 39 while line: 40 line2 = line.rstrip("\n") 41 session = Session(region_name="ap-northeast-1") 42 rekognition = session.client("rekognition") 43 44 response=rekognition.detect_text(Image={'S3Object':{'Bucket':"S3バケット名",'Name':line2}}) 45 46 47 resultfile=line2.lstrip("S3のjpegファイルが格納されたフォルダ名").rstrip(".jpg") 48 textDetections=response['TextDetections'] 49 for text in textDetections: 50 result=open('/tmp/' + resultfile + '.json', 'a', encoding="utf_8") 51 body='Detected text:' + text['DetectedText'] + "\n" 52 result.write(body) 53 result.close 54 line = fileobj.readline() 55 bucket.upload_file('/tmp/' + resultfile + '.json', 'S3の結果出力先フォルダ名' + resultfile + '.json') 56 57 fileobj.close()

現状、こちらのコードでエラーはありません。。
何かご存知の方がいらっしゃいましたらご教授お願いいたします。
どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

あなた自身がここの部分でDetectedTextを抜き出してるから当然そうなるのではないでしょうか?

python

1 textDetections=response['TextDetections'] 2 for text in textDetections: 3 result=open('/tmp/' + resultfile + '.json', 'a', encoding="utf_8") 4 body='Detected text:' + text['DetectedText'] + "\n" 5 result.write(body) 6 result.close

これをやらずに一つ一つ出力結果をファイルに出力して個別にアップロードすればいいと思います。

ついでにいうと、Lambdaの中でfor文を回すのではなく、Lambda Function自体には単一のファイルを処理させてLambdaを呼び出す方で並列実行させるようにしたほうが良いと思います。
Lambdaには実行時間制限(最大15分)があるので、単一のLambda Functionの中で複数の処理をやるのはあまり筋が良くないです。

ただ、同時実行数はデフォルトだと1000になっているので、それを上回りそうであれば緩和申請(特に追加料金はなし)が必要です。

投稿2021/10/05 07:09

yu_1985

総合スコア7447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問