Po wytrenowaniu własnego modelu za pomocą AutoML Vision Edge możesz używać go w aplikacji do wykrywania obiektów na obrazach.
Modele wytrenowane w AutoML Vision Edge można zintegrować na 2 sposoby: możesz dołączyć model, umieszczając go w folderze zasobów aplikacji, lub możesz pobrać go dynamicznie z Firebase.
Opcje pakietów modeli | |
---|---|
Dołączone do aplikacji |
|
Hostowane w Firebase |
|
Zanim zaczniesz
Jeśli chcesz pobrać model, pamiętaj, aby dodać Firebase do projektu na Androida, jeśli jeszcze tego nie zrobisz. Nie jest to wymagane, gdy dołączasz model.
Dodaj zależności biblioteki zadań TensorFlow Lite do pliku Gradle na poziomie aplikacji modułu, który zwykle znajduje się w tym miejscu:
app/build.gradle
W przypadku łączenia modelu z aplikacją:
dependencies { // ... // Object detection with a bundled Auto ML model implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT' }
Aby dynamicznie pobierać model z Firebase, dodaj też zależność 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. Wczytywanie modelu
Konfigurowanie źródła modelu lokalnego
Aby połączyć model z aplikacją:
- Wyodrębnij model z pobranego z Google Cloudkonsoli archiwum ZIP.
- Dołącz model do pakietu aplikacji:
- Jeśli w projekcie nie masz folderu z komponentami, utwórz go, klikając prawym przyciskiem myszy folder
app/
, a następnie wybierając Nowy > Folder > Folder z komponentami. - Skopiuj plik modelu
tflite
z umieszczonymi metadanymi do folderu assets.
- Jeśli w projekcie nie masz folderu z komponentami, utwórz go, klikając prawym przyciskiem myszy folder
Aby mieć pewność, że Gradle nie skompresuje pliku modelu podczas kompilowania aplikacji, dodaj do pliku
build.gradle
ten ciąg:android { // ... aaptOptions { noCompress "tflite" } }
Plik modelu zostanie dołączony do pakietu aplikacji i będzie dostępny jako surowy zasób.
Konfigurowanie źródła modelu hostowanego w Firebase
Aby użyć modelu hostowanego zdalnie, utwórz obiekt RemoteModel
, podając nazwę przypisaną do modelu podczas publikowania:
Java
// 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()
Następnie rozpocznij pobieranie modelu, określając warunki, w których chcesz zezwolić na pobieranie. Jeśli modelu nie ma na urządzeniu lub dostępna jest nowsza wersja, zadanie asynchronicznie pobierze model z Firebase:
Java
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.
}
Wiele aplikacji rozpoczyna pobieranie w kodzie inicjującym, ale możesz to zrobić w dowolnym momencie przed użyciem modelu.
Tworzenie detektora obiektów na podstawie modelu
Po skonfigurowaniu źródeł modelu utwórz z jednego z nich obiekt ObjectDetector
.
Jeśli masz tylko model dołączony lokalnie, utwórz detektor obiektów z pliku modelu i skonfiguruj próg wyniku ufności, który chcesz wymagać (patrz Ocena modelu):
Java
// 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)
Jeśli masz model hostowany zdalnie, przed jego uruchomieniem musisz sprawdzić, czy został pobrany. Stan zadania pobierania modelu możesz sprawdzić za pomocą metody isModelDownloaded()
menedżera modeli.
Chociaż musisz potwierdzić to tylko przed uruchomieniem detektora obiektów, jeśli masz zarówno model hostowany zdalnie, jak i model dołączony lokalnie, warto przeprowadzić to sprawdzenie podczas tworzenia instancji detektora obiektów: utwórz detektor obiektów z modelu zdalnego, jeśli został pobrany, a w przeciwnym razie z modelu lokalnego.
Java
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
}
});
Kotlin
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener { success ->
}
Jeśli masz tylko model hostowany zdalnie, wyłącz funkcje związane z modelem, np. wyszarz lub ukryj część interfejsu, dopóki nie potwierdzisz, że model został pobrany. Możesz to zrobić, dołączając odbiornik do metody download()
menedżera modeli.
Gdy model zostanie pobrany, utwórz detektor obiektów z pliku modelu:
Java
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. Przygotowywanie obrazu wejściowego
Następnie dla każdego obrazu, który chcesz oznaczyć etykietą, utwórz obiekt TensorImage
z obrazu. Możesz utworzyć obiekt TensorImage
z obiektu Bitmap
za pomocą metody fromBitmap
:
Java
TensorImage image = TensorImage.fromBitmap(bitmap);
Kotlin
val image = TensorImage.fromBitmap(bitmap)
Jeśli dane obrazu nie są w formacie Bitmap
, możesz wczytać tablicę pikseli zgodnie z opisem w dokumentacji TensorFlow Lite.
3. Uruchamianie detektora obiektów
Aby wykryć obiekty na obrazie, przekaż obiekt TensorImage
do metody detect()
klasy ObjectDetector
.
Java
List<Detection> results = objectDetector.detect(image);
Kotlin
val results = objectDetector.detect(image)
4. Uzyskiwanie informacji o oznaczonych obiektach
Jeśli operacja wykrywania obiektów się powiedzie, zwraca listę obiektów Detection
. Każdy obiekt Detection
reprezentuje coś, co zostało wykryte na obrazie. Możesz uzyskać ramkę ograniczającą każdego obiektu i jego etykiety.
Przykład:
Java
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()
}
Wskazówki dotyczące zwiększania skuteczności w czasie rzeczywistym
Jeśli chcesz oznaczać obrazy w aplikacji działającej w czasie rzeczywistym, postępuj zgodnie z tymi wskazówkami, aby uzyskać najlepszą liczbę klatek na sekundę:
- Ograniczanie liczby wywołań narzędzia do etykietowania obrazów. Jeśli podczas działania narzędzia do etykietowania obrazów pojawi się nowa klatka wideo, odrzuć ją. Przykład znajdziesz w klasie
VisionProcessorBase
w przykładowej aplikacji z krótkiego wprowadzenia. - Jeśli używasz danych wyjściowych narzędzia do etykietowania obrazów, aby nakładać grafikę na obraz wejściowy, najpierw uzyskaj wynik, a następnie wyrenderuj obraz i nałóż na niego grafikę w jednym kroku. Dzięki temu renderowanie na powierzchnię wyświetlania odbywa się tylko raz dla każdej ramki wejściowej. Przykład znajdziesz w klasach
CameraSourcePreview
iGraphicOverlay
w przykładowej aplikacji z krótkiego wprowadzenia. -
Jeśli używasz interfejsu Camera2 API, rób zdjęcia w formacie
ImageFormat.YUV_420_888
.Jeśli używasz starszego interfejsu Camera API, rób zdjęcia w formacie
ImageFormat.NV21
.