Po wytrenowaniu własnego modelu za pomocą AutoML Vision Edge możesz użyć go w swojej aplikacji do wykrywania obiektów na obrazach.
Istnieją dwa sposoby integrowania modeli wytrenowanych w AutoML Vision Edge: możesz połączyć model w pakiet, umieszczając go w folderze zasobów aplikacji, lub możesz go dynamicznie pobrać z Firebase.
Opcje łączenia modeli | |
---|---|
Dołączone do Twojej aplikacji |
|
Hostowane w Firebase |
|
Zanim zaczniesz
Jeśli chcesz pobrać model , pamiętaj o dodaniu Firebase do swojego projektu na Androida , jeśli jeszcze tego nie zrobiłeś. Nie jest to wymagane w przypadku spakowania modelu.
Dodaj zależności dla biblioteki zadań TensorFlow Lite do pliku gradle na poziomie aplikacji modułu, którym zwykle jest
app/build.gradle
:Aby połączyć model 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 także 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. Załaduj model
Skonfiguruj lokalne źródło modelu
Aby połączyć model z aplikacją:
- Wyodrębnij model z archiwum zip pobranego z konsoli Google Cloud.
- Dołącz swój model do pakietu aplikacji:
- Jeśli nie masz folderu zasobów w swoim projekcie, utwórz go, klikając prawym przyciskiem myszy
app/
folder, a następnie klikając Nowy > Folder > Folder zasobów . - Skopiuj plik modelu
tflite
z osadzonymi metadanymi do folderu zasobów.
- Jeśli nie masz folderu zasobów w swoim projekcie, utwórz go, klikając prawym przyciskiem myszy
Dodaj następujące elementy do pliku
build.gradle
swojej aplikacji, aby mieć pewność, że Gradle nie kompresuje pliku modelu podczas tworzenia aplikacji:android { // ... aaptOptions { noCompress "tflite" } }
Plik modelu zostanie zawarty w pakiecie aplikacji i będzie dostępny jako surowy zasób.
Skonfiguruj źródło modelu hostowane w Firebase
Aby użyć modelu hostowanego zdalnie, utwórz obiekt RemoteModel
, podając nazwę, którą przypisałeś modelowi podczas jego publikowania:
Jawa
// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
new FirebaseCustomRemoteModel.Builder("your_model").build();
Kotlina
// Specify the name you assigned when you deployed the model.
val remoteModel =
FirebaseCustomRemoteModel.Builder("your_model_name").build()
Następnie rozpocznij zadanie pobierania modelu, określając warunki, na jakich chcesz zezwolić na pobieranie. Jeśli modelu nie ma na urządzeniu lub jeśli dostępna jest nowsza wersja modelu, zadanie asynchronicznie pobierze model z Firebase:
Jawa
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.
}
});
Kotlina
val downloadConditions = DownloadConditions.Builder()
.requireWifi()
.build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
.addOnSuccessListener {
// Success.
}
Wiele aplikacji rozpoczyna zadanie pobierania w kodzie inicjującym, ale można to zrobić w dowolnym momencie, zanim będzie konieczne użycie modelu.
Utwórz detektor obiektów na podstawie swojego modelu
Po skonfigurowaniu źródeł modelu utwórz obiekt ObjectDetector
na podstawie jednego z nich.
Jeśli masz tylko model powiązany lokalnie, po prostu utwórz detektor obiektów na podstawie pliku modelu i skonfiguruj wymagany próg wyniku zaufania (zobacz Oceń swój model ):
Jawa
// 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);
Kotlina
// 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 uruchomieniem musisz sprawdzić, czy został pobrany. Możesz sprawdzić status zadania pobierania modelu, korzystając z metody isModelDownloaded()
menedżera modeli.
Chociaż musisz to potwierdzić jedynie przed uruchomieniem detektora obiektów, jeśli masz zarówno model hostowany zdalnie, jak i model powiązany lokalnie, sensowne może być wykonanie tej kontroli podczas tworzenia instancji detektora obiektów: utwórz detektor obiektów ze zdalnego model, jeśli został pobrany, lub z modelu lokalnego w przeciwnym razie.
Jawa
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
}
});
Kotlina
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener { success ->
}
Jeśli masz tylko model hostowany zdalnie, wyłącz funkcje związane z modelem — na przykład wyszarz lub ukryj część interfejsu użytkownika — do czasu potwierdzenia, że model został pobrany. Można to zrobić, dołączając odbiornik do metody download()
menedżera modelu.
Kiedy już wiesz, że Twój model został pobrany, utwórz detektor obiektów na podstawie pliku modelu:
Jawa
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);
}
}
});
Kotlina
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
.addOnSuccessListener { modelFile ->
val options = ObjectDetectorOptions.builder()
.setScoreThreshold(0f)
.build()
objectDetector = ObjectDetector.createFromFileAndOptions(
applicationContext, modelFile.path, options)
}
2. Przygotuj obraz wejściowy
Następnie dla każdego obrazu, który chcesz oznaczyć etykietą, utwórz na podstawie obrazu obiekt TensorImage
. Możesz utworzyć obiekt TensorImage
z Bitmap
za pomocą metody fromBitmap
:
Jawa
TensorImage image = TensorImage.fromBitmap(bitmap);
Kotlina
val image = TensorImage.fromBitmap(bitmap)
Jeśli danych obrazu nie ma w Bitmap
, możesz załadować tablicę pikseli, jak pokazano w dokumentacji TensorFlow Lite .
3. Uruchom detektor obiektów
Aby wykryć obiekty na obrazie, przekaż obiekt TensorImage
do metody detect()
obiektu ObjectDetector
.
Jawa
List<Detection> results = objectDetector.detect(image);
Kotlina
val results = objectDetector.detect(image)
4. Uzyskaj informacje o oznaczonych obiektach
Jeśli operacja wykrywania obiektu powiedzie się, zwraca listę obiektów Detection
. Każdy obiekt Detection
reprezentuje coś, co zostało wykryte na obrazie. Możesz pobrać obwiednię każdego obiektu i jego etykiety.
Na przykład:
Jawa
for (Detection result : results) {
RectF bounds = result.getBoundingBox();
List<Category> labels = result.getCategories();
}
Kotlina
for (result in results) {
val bounds = result.getBoundingBox()
val labels = result.getCategories()
}
Wskazówki, jak poprawić wydajność w czasie rzeczywistym
Jeśli chcesz oznaczać obrazy w aplikacji działającej w czasie rzeczywistym, postępuj zgodnie z poniższymi wskazówkami, aby uzyskać najlepszą liczbę klatek na sekundę:
- Ogranicz wywołania do modułu etykietowania obrazów. Jeśli w trakcie działania narzędzia do etykietowania obrazów dostępna będzie nowa klatka wideo, usuń ją. Aby zapoznać się z przykładem, zobacz klasę
VisionProcessorBase
w przykładowej aplikacji szybkiego startu. - Jeśli używasz danych wyjściowych modułu etykietowania obrazów do nakładania grafiki na obraz wejściowy, najpierw uzyskaj wynik, a następnie wyrenderuj obraz i nakładkę w jednym kroku. W ten sposób renderujesz na powierzchnię wyświetlacza tylko raz dla każdej klatki wejściowej. Aby zapoznać się z przykładem, zobacz klasy
CameraSourcePreview
iGraphicOverlay
w przykładowej aplikacji szybkiego startu. Jeśli korzystasz z interfejsu API Camera2, przechwytuj obrazy w formacie
ImageFormat.YUV_420_888
.Jeśli używasz starszego interfejsu Camera API, przechwytuj obrazy w formacie
ImageFormat.NV21
.