AutoML Vision Edge를 사용하여 자체 모델을 학습시킨 후 앱에서 이 모델을 사용해 이미지에서 객체를 감지할 수 있습니다.
AutoML Vision Edge에서 학습된 모델을 통합하는 방법에는 2가지가 있습니다. 앱의 애셋 폴더에 모델을 저장하여 번들로 묶거나 Firebase에서 동적으로 다운로드하는 것입니다.
모델 번들 옵션 | |
---|---|
앱에 번들로 제공 |
|
Firebase로 호스팅 |
|
시작하기 전에
모델을 다운로드하려면 Android 프로젝트에 Firebase를 추가(아직 추가하지 않은 경우)해야 합니다. 모델을 번들로 묶을 때는 이 작업이 필요하지 않습니다.
모듈의 앱 수준 Gradle 파일(일반적으로
app/build.gradle
)에 TensorFlow Lite Task 라이브러리의 종속 항목을 추가합니다.모델을 앱과 함께 번들로 묶는 방법은 다음과 같습니다.
dependencies { // ... // Object detection with a bundled Auto ML model implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT' }
Firebase에서 모델을 동적으로 다운로드하려면 Firebase ML 종속 항목도 추가하세요.
dependencies { // ... // Object detection with an Auto ML model deployed to Firebase implementation platform('com.google.firebase:firebase-bom:26.1.1') implementation 'com.google.firebase:firebase-ml-model-interpreter' implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly' }
1. 모델 로드
로컬 모델 소스 구성
모델을 앱과 함께 번들로 묶는 방법은 다음과 같습니다.
- Google Cloud Console에서 다운로드한 zip 보관 파일에서 모델을 추출합니다.
- 앱 패키지에 모델을 포함합니다.
- 프로젝트에 애셋 폴더가 없으면
app/
폴더를 마우스 오른쪽 버튼으로 클릭하고 새로 만들기 > 폴더 > 애셋 폴더를 클릭하여 하나 만듭니다. - 메타데이터가 삽입된
tflite
모델 파일을 애셋 폴더에 복사합니다.
- 프로젝트에 애셋 폴더가 없으면
Gradle이 앱을 빌드할 때 모델 파일을 압축하지 않도록 앱의
build.gradle
파일에 다음을 추가합니다.android { // ... aaptOptions { noCompress "tflite" } }
모델 파일이 앱 패키지에 포함되며 원시 애셋으로 사용할 수 있습니다.
Firebase 호스팅 모델 소스 구성
원격 호스팅 모델을 사용하려면 모델을 게시할 때 모델에 할당한 이름을 지정하여 RemoteModel
객체를 만듭니다.
자바
// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
new FirebaseCustomRemoteModel.Builder("your_model").build();
Kotlin
// Specify the name you assigned when you deployed the model.
val remoteModel =
FirebaseCustomRemoteModel.Builder("your_model_name").build()
이제 다운로드를 허용할 조건을 지정하여 모델 다운로드 작업을 시작합니다. 모델이 기기에 없거나 최신 버전의 모델을 사용할 수 있으면 모델이 Firebase에서 비동기식으로 다운로드됩니다.
자바
DownloadConditions downloadConditions = new DownloadConditions.Builder()
.requireWifi()
.build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(@NonNull Task<Void> task) {
// Success.
}
});
Kotlin
val downloadConditions = DownloadConditions.Builder()
.requireWifi()
.build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
.addOnSuccessListener {
// Success.
}
대부분의 앱은 초기화 코드로 다운로드 작업을 시작하지만 모델 사용이 필요한 시점 이전에는 언제든지 다운로드할 수 있습니다.
모델에서 객체 감지기 만들기
모델 소스를 구성한 후 모델 소스 중 하나에서 ObjectDetector
객체를 만듭니다.
로컬로 번들된 모델만 있는 경우 모델 파일에서 객체 감지기를 만들고 필요한 신뢰도 점수 임곗값을 구성합니다(모델 평가 참조).
자바
// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
.setScoreThreshold(0) // Evaluate your model in the Google Cloud Console
// to determine an appropriate value.
.build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);
Kotlin
// Initialization
val options = ObjectDetectorOptions.builder()
.setScoreThreshold(0) // Evaluate your model in the Google Cloud Console
// to determine an appropriate value.
.build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)
원격 호스팅 모델이 있다면 실행 전에 모델이 다운로드되었는지 확인해야 합니다. 모델 관리자의 isModelDownloaded()
메서드로도 모델 다운로드 작업의 상태를 확인할 수 있습니다.
이 상태는 객체 감지기를 실행하기 전에만 확인하면 되지만, 원격 호스팅 모델과 로컬로 번들된 모델이 모두 있는 경우에는 객제 감지기를 인스턴스화할 때 이 확인 작업을 수행하는 것이 합리적일 수 있으며 원격 모델이 다운로드되었으면 원격 모델에서, 그렇지 않으면 로컬 모델에서 객체 감지기를 만듭니다.
자바
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
}
});
Kotlin
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener { success ->
}
원격 호스팅 모델만 있다면 모델 다운로드 여부가 확인될 때까지 모델 관련 기능 사용을 중지해야 합니다(예: UI 비활성화 또는 숨김). 모델 관리자의 download()
메서드에 리스너를 연결하여 관련 기능을 사용 중지할 수도 있습니다.
모델이 다운로드된 것이 확인되었으면 모델 파일에서 객체 감지기를 만듭니다.
자바
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
.addOnCompleteListener(new OnCompleteListener<File>() {
@Override
public void onComplete(@NonNull Task<File> task) {
File modelFile = task.getResult();
if (modelFile != null) {
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
.setScoreThreshold(0)
.build();
objectDetector = ObjectDetector.createFromFileAndOptions(
getApplicationContext(), modelFile.getPath(), options);
}
}
});
Kotlin
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
.addOnSuccessListener { modelFile ->
val options = ObjectDetectorOptions.builder()
.setScoreThreshold(0f)
.build()
objectDetector = ObjectDetector.createFromFileAndOptions(
applicationContext, modelFile.path, options)
}
2. 입력 이미지 준비
그런 다음 라벨을 지정할 각 이미지에서 TensorImage
객체를 만듭니다. fromBitmap
메서드를 사용하여 Bitmap
에서 TensorImage
객체를 만들 수 있습니다.
자바
TensorImage image = TensorImage.fromBitmap(bitmap);
Kotlin
val image = TensorImage.fromBitmap(bitmap)
이미지 데이터가 Bitmap
에 없는 경우 TensorFlow Lite 문서에 표시된 대로 픽셀 배열을 로드할 수 있습니다.
3. 객체 감지기 실행
이미지에서 객체를 감지하려면 TensorImage
객체를 ObjectDetector
의 detect()
메서드에 전달합니다.
자바
List<Detection> results = objectDetector.detect(image);
Kotlin
val results = objectDetector.detect(image)
4. 라벨이 지정된 객체 정보 가져오기
객체 감지 작업이 성공하면 Detection
객체 목록이 반환됩니다. 각 Detection
객체는 이미지에서 감지된 항목을 나타냅니다. 각 객체의 경계 상자와 라벨을 가져올 수 있습니다.
예를 들면 다음과 같습니다.
자바
for (Detection result : results) {
RectF bounds = result.getBoundingBox();
List<Category> labels = result.getCategories();
}
Kotlin
for (result in results) {
val bounds = result.getBoundingBox()
val labels = result.getCategories()
}
실시간 성능 향상을 위한 팁
실시간 애플리케이션에서 이미지 라벨을 지정하려는 경우 최상의 프레임 속도를 얻으려면 다음 안내를 따르세요.
- 이미지 라벨러 호출을 제한합니다. 이미지 라벨러가 실행 중일 때 새 동영상 프레임이 제공되는 경우 해당 프레임을 삭제합니다. 관련 예시는 빠른 시작 샘플 앱에서
VisionProcessorBase
클래스를 참조하세요. - 이미지 라벨러 출력을 사용해 입력 이미지에서 그래픽을 오버레이하는 경우 먼저 인식 결과를 가져온 후 이미지를 렌더링하고 단일 단계로 오버레이합니다. 이렇게 하면 입력 프레임별로 한 번만 디스플레이 표면에 렌더링됩니다. 관련 예시는 빠른 시작 샘플 앱에서
CameraSourcePreview
및GraphicOverlay
클래스를 참조하세요. -
Camera2 API를 사용할 경우
ImageFormat.YUV_420_888
형식으로 이미지를 캡처합니다.이전 Camera API를 사용하는 경우
ImageFormat.NV21
형식으로 이미지를 캡처합니다.