상세 컨텐츠

본문 제목

[Firebase + Android + Tensorflow] tflite모델을 이용해 Camera로 찍은 사진을 분류, Firebase Cloud Storage에 Upload하기(JAVA)

IT Convergence Engineering/AI 버섯 어플

by Soo_buglosschestnut 2020. 8. 14. 22:52

본문

tflite모델을 이용해 Camera로 찍은 사진을 분류, Firebase Cloud Storage에 Upload하기(JAVA)


  • tflite모델을 사용하기 위한 환경설정을 마치고 난 후에 사용할 수 있다.(assets폴더, gradlue 코드 수정 등)

https://bugloss-chestnut.tistory.com/entry/Android-h5-pb-tflite%EB%A1%9C-%EB%B3%80%ED%99%98-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%97%90-%EC%A0%81%EC%9A%A9?category=955919

 

[Tensorflow & Android] .h5 -> .pb -> .tflite로 변환 & 안드로이드에 적용(python & java)

.h5 -> .pb -> .tflite로 변환 & 안드로이드에 적용(python & java) 1. .h5 -> .pb -> .tflite로 변환 .h5 파일 -> .pb 파일로 변환하기 (코드) from tensorflow import keras model = keras.models.load_model(..

bugloss-chestnut.tistory.com

 

  • 또, Firebase Cloud Storage 관련 환경설정을 마치고 난 후에 사용이 가능하다.

- Firebase 이용하기

https://bugloss-chestnut.tistory.com/entry/Firebase-Android-Google-%EA%B3%84%EC%A0%95%EC%9C%BC%EB%A1%9C-Firebase-%EC%9D%B4%EC%9A%A9%ED%95%98%EA%B8%B0-Android-Project%EC%97%90-Firebase-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0JAVA?category=955919

 

[Firebase + Android] Google 계정으로 Firebase 이용하기 & Firebase에 Android Project 추가하기(JAVA)

Google 계정으로 Firebase 이용하기 &  Firebase에 Android Project 추가하기(JAVA) 구글 계정 로그인 후 아래 링크를 통해 Firebase Console들어가기 https://console.firebase.google.com/u/0/?hl=ko 로그인 -..

bugloss-chestnut.tistory.com

- Firebase Android에서 이용해보기

https://bugloss-chestnut.tistory.com/entry/Firebase-Android-Android-App%EC%9C%BC%EB%A1%9C-Firebase-Cloud-Storage-%EC%9D%B4%EC%9A%A9%ED%95%98%EA%B8%B0JAVA?category=955919

 

[Firebase + Android] Android App으로 Firebase Cloud Storage 이용하기(JAVA)

Android App으로 Firebase Cloud Storage 이용하기(JAVA) 1. Firebase console 들어가기 → 전에 만들어 두었던 Project가 생성되어 있음! 2. 왼쪽 Storage Click!! 3. 시작하기 Click 4. 완료 Click!! 6..

bugloss-chestnut.tistory.com


  • Andorid App에서 Camera앱을 통해 사진찍어 보기

- Manifest 추가 Code

<uses-permission android:name="android.permission.CAMERA" />

Camera 허용 code

 

- MainActivity 일부 Code

static final int REQUEST_IMAGE_CAPTURE = 1;

private void openCamera() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
    }

- 실행결과

 

 

 

 

 

 

 

 

 

 

     → App 실행시 후, 사진 촬영 Button Click 시 Camera가 작동됨 (Button 눌러 동작 Code 따로 구현 했음.)

 

 

 

 

 

 

 

더보기

 

  • Camera로 찍은 사진, 핸드폰 외부 저장소에 저장하기

- Manifest 추가 Code 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

<!--찍은 사진 저장할려면 필요 - 추가하기-->
        <meta-data
            android:name="com.google.android.actions"
            android:resource="@xml/file_paths" />
<!--찍은 사진 저장할려면 필요 - 추가하기-->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.android.######.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

→ ######에는 자신의 package 주소를 쓰면 된다.

 

올바른 위치에 code 작성

<meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />

→ resource = "@xml/file_paths" --> xml파일 안에 file_paths라고 지정된 folder에 사진 저장됨.

 

 

- res/ xml folder 생성하기

 

 

 

 

 

1. 위와 같은 방법으로 Directory 추가 Click

 

 

 

 

 

 

 

 

 

 

 

2. xml type으로 설정 후 OK

 

 

 

 

 

 

 

 

 

 

 

3. xml에 folder에 새로운 file_paths.xml file 생성하기

 

 

 

 

 

 

file_paths.xml 파일 생성 완료

  - file_paths.xml code

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="image_capture" path="Pictures/" />
</paths>

 

→ 이렇게 설정한 후, 밑에처럼 opencamera 코드를 수정해 주면 찍은 사진이 핸드폰에 저장되게 된다.

 

- MainActivity 일부 추가 Code

static final int REQUEST_IMAGE_CAPTURE = 1;
private String mPhotoFileName = null;
private File mPhotoFile = null;
private Uri imageUri;

private void openCamera() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (cameraIntent.resolveActivity(getPackageManager()) != null) {
            //1. 카메라 앱으로 찍은 이미지를 저장할 파일 객체 생성
            mPhotoFileName = "IMG" + currentDateFormat() + ".jpg";
            mPhotoFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), mPhotoFileName);

            if (mPhotoFile != null) {
                //2. 생성된 파일 객체에 대한 Uri 객체를 얻기
                 imageUri = FileProvider.getUriForFile(this, "com.android.######.fileprovider", mPhotoFile);

                //3. Uri 객체를 Extras를 통해 카메라 앱으로 전달
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);

            } else
                Toast.makeText(getApplicationContext(), "file null", Toast.LENGTH_SHORT).show();
        }
    }

→ ######에는 자신의 package 주소를 쓰면 된다.

 

→ 이미지 Uri를 통해서 사진을 저장하고 넘겨준다.

 

- 실행 결과

 

이미지 이름은 찍은 날짜+시간


  • 저장된 사진 File 이용해 Firebase Cloud Storage에 Upload하기 

https://bugloss-chestnut.tistory.com/entry/Android-h5-pb-tflite%EB%A1%9C-%EB%B3%80%ED%99%98-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%97%90-%EC%A0%81%EC%9A%A9?category=955919

 

[Tensorflow & Android] .h5 -> .pb -> .tflite로 변환 & 안드로이드에 적용(python & java)

.h5 -> .pb -> .tflite로 변환 & 안드로이드에 적용(python & java) 1. .h5 -> .pb -> .tflite로 변환 .h5 파일 -> .pb 파일로 변환하기 (코드) from tensorflow import keras model = keras.models.load_model(..

bugloss-chestnut.tistory.com

https://bugloss-chestnut.tistory.com/entry/Firebase-Android-Android-App%EC%9C%BC%EB%A1%9C-Firebase-Cloud-Storage-%EC%9D%B4%EC%9A%A9%ED%95%98%EA%B8%B0JAVA

 

[Firebase + Android] Android App으로 Firebase Cloud Storage 이용하기(JAVA)

Android App으로 Firebase Cloud Storage 이용하기(JAVA) 1. Firebase console 들어가기 → 전에 만들어 두었던 Project가 생성되어 있음! 2. 왼쪽 Storage Click!! 3. 시작하기 Click 4. 완료 Click!!..

bugloss-chestnut.tistory.com

↑ 위의 게시물 코드 이용 예정

 

- Code

 

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // camera 사용 code 이고 result_ok일시 작동
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            // image_w /h (?,224,224,3) shape 3 -> rgb
            // tflite 모델 image가 width/height 각각  224, 224 size
            float[][][][] input = new float[1][224][224][3];

            int batchNum = 0;

            // 저장된 사진 mPhotoFile을 bitmap으로 decodeFile
            Bitmap bitmap = BitmapFactory.decodeFile(mPhotoFile.getAbsolutePath());
            // imageview 사진 뜨게함
            image.setImageBitmap(bitmap);

            for (int x = 0; x < 224; x++) {
                for (int y = 0; y < 224; y++) {
                    int pixel = bitmap.getPixel(x, y);
                    input[batchNum][x][y][0] = Color.red(pixel) / 1.0f;
                    input[batchNum][x][y][1] = Color.green(pixel) / 1.0f;
                    input[batchNum][x][y][2] = Color.blue(pixel) / 1.0f;
                }
            }


            // pass this bitmap to classifier to make prediction
            List<ImageClassifier.Recognition> predicitons = imageClassifier.recognizeImage(
                    bitmap, 0);
            // creating a list of string to display in list view
            final List<String> predicitonsList = new ArrayList<>();

            for (ImageClassifier.Recognition recog : predicitons) {
                // 일치 확률 50% 일시 listview 작성
                if (recog.getConfidence() * 100 >= 50) {
                    predicitonsList.add(recog.getName() + "와(과)  " + recog.getConfidence() * 100 + "%  일치");
                    if (imageUri != null) {

                        /*
                         * firebase기반으로 한 cloud storage -> 사용자가 찍은 image를 cloud storage로 넘김
                         */

                        // image를 cloud로 넘길때 이름

                        String filename = recog.getName() + recog.getConfidence() * 100 + "__" + currentDateFormat()+ ".jpg";

                        // image를 넘길 폴더
                        String foldername = recog.getName() + "/";

                        // reference 생성
                        FirebaseStorage storage = FirebaseStorage.getInstance();
                        StorageReference storageRef = storage.getReferenceFromUrl("gs://#######.appspot.com").child(foldername + filename);
                        
                        storageRef.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                            @Override
                            // coloud storage에 image 업로드 성공시
                            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                Toast.makeText(getApplicationContext(), "업로드 완료!", Toast.LENGTH_SHORT).show();
                                Log.e("Firebase cloud storage","Upload Success!");
                            }
                        })
                                //실패시
                                .addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        Toast.makeText(getApplicationContext(), "업로드 실패!", Toast.LENGTH_SHORT).show();
                                        Log.e("Firebase cloud storage","Upload Fail!");
                                    }
                                })
                                //진행중
                                .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                                    @Override
                                    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                                        Log.e("Firebase cloud storage","Loading!");
                                    }
                                });
                    } else {
                        Toast.makeText(getApplicationContext(), "파일을 먼저 선택하세요.", Toast.LENGTH_SHORT).show();
                    }
                }
                else if(recog.getConfidence() * 100 < 50){
                    mush_output.setText("일치하는 버섯이 존재하지 않습니다.");
                }
            }

            // creating an array adapter to display the classification result in list view
            ArrayAdapter<String> predictionsAdapter = new ArrayAdapter<>(
                    this, R.layout.support_simple_spinner_dropdown_item, predicitonsList);
            listView.setAdapter(predictionsAdapter);

        }
    }

- 참조

 

 

 

- 실행 결과

 

 

→ 모델 잘 작동 후, folder에 사진 저장 작동

 

 

→ Cloud에 잘 저장됨.

 

 


ⓐ 사진찍은거 gallery 저장

관련글 더보기