Gdy wytrenujesz własny model przy użyciu AutoML Vision Edge, możesz używać go w swojej aplikacji do wykrywania obiektów na obrazach.
Istnieją 2 sposoby integracji modeli wytrenowanych w AutoML Vision Edge: skompiluj model, umieszczając go w folderze zasobów aplikacji. pobierać dynamicznie je z Firebase.
Opcje grupowania modeli | |
---|---|
Pakiet w aplikacji |
|
Hostowane w Firebase |
|
Zanim zaczniesz
Jeśli chcesz pobrać model, dodaj Firebase do projektu na Androida, jeśli nie zostało to jeszcze zrobione. Nie jest to wymagane, gdy model jest w pakiecie.
Dodaj zależności do biblioteki zadań TensorFlow Lite do biblioteki modułu plik Gradle na poziomie aplikacji, który zwykle ma wartość
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 również Firebase ML zależność:
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. Wczytaj model
Skonfiguruj źródło modelu lokalnego
Aby połączyć model z aplikacją:
- Rozpakuj model z archiwum ZIP pobranego z Konsola Google Cloud.
- Umieść model w pakiecie aplikacji:
- Jeśli w projekcie nie masz folderu komponentów, utwórz go, klikając
app/
prawym przyciskiem myszy, a następnie Nowy > Folder > Folder komponentów. - Skopiuj do zasobów plik modelu
tflite
z osadzonymi metadanymi folderu Dysku.
- Jeśli w projekcie nie masz folderu komponentów, utwórz go, klikając
Dodaj te fragmenty do pliku
build.gradle
z informacjami o aplikacji, aby mieć pewność, że: Gradle nie kompresuje pliku modelu podczas tworzenia aplikacji:android { // ... aaptOptions { noCompress "tflite" } }
Plik modelu zostanie dołączony do pakietu aplikacji i będzie dostępny jako nieprzetworzony zasób.
Skonfiguruj źródło modelu hostowanego w Firebase
Aby używać modelu hostowanego zdalnie, utwórz obiekt RemoteModel
,
określając nazwę przypisaną do modelu podczas jego 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 uruchom zadanie pobierania modelu, określając warunki, które którym chcesz zezwolić na pobieranie. Jeśli nie ma modelu na urządzeniu lub jest on nowszy gdy dostępna będzie wersja modelu, 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 zadanie pobierania w kodzie inicjowania, możesz to zrobić w dowolnym momencie, zanim trzeba będzie skorzystać z modelu.
Tworzenie wzorca do wykrywania obiektów na podstawie modelu
Po skonfigurowaniu źródeł modelu utwórz obiekt ObjectDetector
na podstawie jednego
z nich.
Jeśli masz tylko model dołączony lokalnie, utwórz wzorzec do wykrywania obiektów na podstawie pliku modelu i skonfigurować wskaźnik ufności próg, który chcesz zastosować (zobacz 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, musisz sprawdzić, czy został
pobrane przed uruchomieniem. Stan pobierania modelu możesz sprawdzić
za pomocą metody isModelDownloaded()
menedżera modeli.
Mimo że musisz to potwierdzić tylko przed uruchomieniem wykrywania obiektów, korzystają zarówno z modelu hostowanego zdalnie, jak i z pakietu lokalnego, może to sprawić, warto przeprowadzić tę kontrolę przy tworzeniu wystąpienia detektora obiektów: utwórz detektora obiektów z modelu zdalnego, jeśli został pobrany, oraz z lokalnego w inny sposób.
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. wygaszaj lub ukryj część interfejsu użytkownika), dopóki nie potwierdzisz, że model został pobrany. Aby to zrobić, dołącz detektor
do metody download()
menedżera modeli.
Gdy dowiesz się, że model został pobrany, utwórz detektor obiektów w plik 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
na podstawie
. Obiekt TensorImage
możesz utworzyć z Bitmap
za pomocą
Metoda fromBitmap
:
Java
TensorImage image = TensorImage.fromBitmap(bitmap);
Kotlin
val image = TensorImage.fromBitmap(bitmap)
Jeśli danych obrazu nie ma w formacie Bitmap
, możesz wczytać tablicę pikseli w sposób pokazany na
dokumentach TensorFlow Lite.
3. Uruchom detektor obiektów
Aby wykrywać obiekty na obrazie, przekaż obiekt TensorImage
do funkcji
Metoda detect()
użytkownika ObjectDetector
.
Java
List<Detection> results = objectDetector.detect(image);
Kotlin
val results = objectDetector.detect(image)
4. Uzyskiwanie informacji o obiektach oznaczonych etykietami
Jeśli operacja wykrywania obiektów zakończy się powodzeniem, zwróci listę obiektów Detection
. Każdy obiekt Detection
reprezentuje coś, co zostało wykryte w
. Możesz pobrać ramkę ograniczającą każdego obiektu i jej 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 poprawy skuteczności w czasie rzeczywistym
Jeśli chcesz oznaczać obrazy w aplikacji działającej w czasie rzeczywistym, postępuj zgodnie z tymi instrukcjami wytycznych dotyczących uzyskiwania najlepszej liczby klatek na sekundę:
- Ogranicz wywołania do osoby oznaczającej obrazy. Jeśli nowa klatka wideo
dostępne podczas działania narzędzia do etykietowania obrazów, upuść ramkę. Przykładem jest klasa
VisionProcessorBase
w przykładowej aplikacji krótkiego wprowadzenia. - Jeśli używasz danych wyjściowych osoby oznaczającej obrazy do nakładania grafiki na
obraz wejściowy, najpierw uzyskaj wynik, a następnie wyrenderuj obraz
i nakładanie nakładek w jednym kroku. W ten sposób renderujesz na powierzchni wyświetlacza tylko raz w przypadku każdej ramki wejściowej. Zobacz
CameraSourcePreview
iGraphicOverlay
w przykładowej aplikacji z krótkim wprowadzeniem dla przykład. -
Jeśli używasz interfejsu Camera2 API, rób zdjęcia w formacie
ImageFormat.YUV_420_888
.Jeśli używasz starszej wersji interfejsu Camera API, rób zdjęcia w formacie
ImageFormat.NV21
.