(안드로이드) AWS Rekognition API 사용

(Amazon Rekognition 이미지(nodejs)에서 텍스트 감지) https://sssbin./185

이번에는 Android에서 Rekognition API를 사용해 봅니다.

(사실 1년전에 했던 프로젝트인데…)

사용자가 카메라로 사진을 찍으면 S3 버킷에 업로드하고 Rekognition 수행 결과를 반환합니다.

AWS 설정

– IAM 계정, 새로운 S3 버킷(위 링크 참조)

– Amazon Cognito 자격 증명 풀 생성

– 로그인 기능 X -> 인증되지 않은 자격 증명에 대한 액세스 활성화(Unauth)

– 인지 역량 강화

– IAM > 역할 > Cognito 자격 증명 풀 생성 시 생성된 역할 선택(비인증) > 권한 추가

– IAMFullAccess, AmazonS3FullAccess, AmazonRekognitionFullAccess, AdministratorAccess

프로젝트 설정

build.gradle(app) -> 의존성 추가

implementation 'com.amazonaws:aws-android-sdk-mobile-client:2.13.5'
implementation 'com.amazonaws:aws-android-sdk-cognito:2.13.5'
implementation 'com.amazonaws:aws-android-sdk-s3:2.13.5'

매니페스트 -> 권한 부여, 서비스 추가

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
	...
	<service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService" android:enabled="true"/>
	...    
</application>

코드

– Amazon Cognito 인증 공급자, S3 객체 설정

– 카메라 -> 이미지 파일 생성 -> URI 생성 -> S3 버킷에 업로드

-> Rekognition 클라이언트 객체 생성 -> DetectText 요청

package kr.co.company.canfindcan;

import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferState;
import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.rekognition.AmazonRekognition;
import com.amazonaws.services.rekognition.AmazonRekognitionClient;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.services.rekognition.model.DetectTextRequest;
import com.amazonaws.services.rekognition.model.DetectTextResult;
import com.amazonaws.services.rekognition.model.Image;
import com.amazonaws.services.rekognition.model.S3Object;
import com.amazonaws.services.rekognition.model.TextDetection;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;

import java.io.File;
import java.io.IOException;
import java.util.List;


public class RekogActivity extends AppCompatActivity {
    private final static String TAG = "CANFINDCAN";
    public final static String PREFS_NAME = "MyPrefsFile";

    static final int REQUEST_IMAGE_CAPTURE = 1;
    static final int REQUEST_TAKE_PHOTO = 1;

    String mCurrentPhotoPath;

    private FrameLayout capture;

    File img;

    AmazonS3 s3;
    TransferUtility transferUtility;
    CognitoCachingCredentialsProvider credentialsProvider;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rekog);
        capture = (FrameLayout) findViewById(R.id.capture);

        // Amazon Cognito 인증 공급자 설정
        credentialsProvider = new CognitoCachingCredentialsProvider(
                getApplicationContext(),
                "------", // 자격 증명 풀 ID
                Regions.AP_NORTHEAST_2 // 리전
        );

        // s3 클라이언트 설정
        s3 = new AmazonS3Client(credentialsProvider);
        transferUtility = new TransferUtility(s3, getApplicationContext());

        s3.setRegion(Region.getRegion(Regions.AP_NORTHEAST_2));
        s3.setEndpoint("s3.ap-northeast-2.amazonaws.com");


        // 카메라 버튼
        capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dispatchTakePictureIntent();
            }
        });
    }

    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (takePictureIntent.resolveActivity(getPackageManager()) !
= null) { File photoFile = null; try { // 이미지 파일 생성 photoFile = createImageFile(); } catch (IOException ex) { Log.e("ERROR", ex.getMessage(), ex); // 사진 촬영 실패 } if (photoFile !
= null) { // URI 생성 img = photoFile; Uri photoURI = FileProvider.getUriForFile(this, "kr.co.company.canfindcan.fileprovider", // "패키지명.fileproivder" photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); } else { // 사진 촬영 실패 } } } private File createImageFile() throws IOException { Log.i(TAG, "Creating image file"); String imageFileName = "can_images"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = "file:" + image.getAbsolutePath(); Log.i(TAG, "Image created and returned"); return image; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { // 이미지 파일 & URI 생성 -> request 성공적이면 -> S3 버킷에 업로드 upload(); } } public void upload() { String imgName = "uploadImg"; SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putString("curImg", imgName); editor.commit(); if (img == null) { Log.i("ERROR", "The file is empty"); } else { TransferObserver observer = transferUtility.upload( "------", // The bucket to upload to "upload_test.jpg", // The key for the uploaded object img, // 위에서 생성한 이미지 파일 객체 CannedAccessControlList.PublicRead ); observer.setTransferListener(new TransferListener() { public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) { Log.i(TAG, "progress changed"); } public void onStateChanged(int id, TransferState state) { if (state == TransferState.COMPLETED) { Log.i(TAG, "state changed"); DetectText(); // 텍스트 감지 (Rekognition) } } public void onError(int id, Exception ex) { Log.e("ERROR", ex.getMessage(), ex); // 오류 발생 } }); } } public void DetectText() { String photo = "upload_test.jpg"; // The key for the uploaded object String bucket = "------"; // The bucket to upload to AWSCredentials cre = new AWSCredentials() { // IAM 계정 생성할 때 받은 키 넣어주기 @Override public String getAWSAccessKeyId() { return "------"; } @Override public String getAWSSecretKey() { return "------"; } }; // RekognitionClient 객체 생성 AmazonRekognition rekognitionClient = new AmazonRekognitionClient(cre); rekognitionClient.setRegion(Region.getRegion(Regions.AP_NORTHEAST_2)); // 요청 객체(?) DetectTextRequest request = new DetectTextRequest() .withImage(new Image() .withS3Object(new S3Object() .withName(photo) .withBucket(bucket))); String res =""; // 텍스트 결과값 // DetectText 요청 try { AsyncTask<DetectTextRequest,Void,String> asyncTask = new AsyncTask<DetectTextRequest, Void, String>() { @Override protected String doInBackground(DetectTextRequest... detectTextRequests) { DetectTextResult result = rekognitionClient.detectText(request); List<TextDetection> textDetections = result.getTextDetections(); System.out.println("Detected lines and words for " + photo); String res=""; for (TextDetection text: textDetections) { if (text.getId() == 0) { // 원하는 값만 얻으려면 첫번째 줄만 필요함. res = text.getDetectedText(); break; } } return res; } }; // 텍스트 감지 결과값 !
!
!
!
res = asyncTask.execute(request).get(); }catch (Exception e){ System.out.println(e); // 텍스트 감지 실패 !
!
!
!
} } }

그게 다야..

공식 문서에 제공된 코드는… 지원되지 않아서 당황스럽네요

텍스트 감지 결과는 res에 저장되므로 이제 원하는 대로 사용할 수 있습니다.

이와 같이…