Mit Firebase ML können Sie Objekte kennzeichnen, die in einem Bild erkannt wurden. Informationen zu den Funktionen dieser API finden Sie in der Übersicht.
Hinweis
- Fügen Sie Ihrem Android-Projekt Firebase hinzu, falls noch nicht geschehen.
-
Fügen Sie in der Gradle-Datei Ihres Moduls (auf App-Ebene) (in der Regel
<project>/<app-module>/build.gradle.kts
oder<project>/<app-module>/build.gradle
) die Abhängigkeit für die Firebase ML Vision-Bibliothek für Android hinzu. Wir empfehlen, die Firebase Android BoM zu verwenden, um die Versionsverwaltung der Bibliothek zu steuern.dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:34.0.0")) // Add the dependency for the Firebase ML Vision library // When using the BoM, you don't specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-ml-vision' }
Mit der Firebase Android BoM haben Sie immer eine kompatible Version der Firebase Android-Bibliotheken in Ihrer App.
(Alternative) Firebase-Bibliotheksabhängigkeiten ohne Verwendung von BoM hinzufügen
Wenn Sie die Firebase BoM nicht verwenden möchten, müssen Sie jede Firebase-Bibliotheksversion in der entsprechenden Abhängigkeitszeile angeben.
Wenn Sie mehrere Firebase-Bibliotheken in Ihrer App verwenden, empfehlen wir dringend, die BoM zum Verwalten von Bibliotheksversionen zu verwenden, um sicherzustellen, dass alle Versionen kompatibel sind.
dependencies { // Add the dependency for the Firebase ML Vision library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-ml-vision:24.1.0' }
-
Wenn Sie cloudbasierte APIs für Ihr Projekt noch nicht aktiviert haben, holen Sie dies jetzt nach:
- Öffnen Sie in der Firebase-Konsole die Seite Firebase ML APIs.
-
Wenn Sie Ihr Projekt noch nicht auf den Blaze-Tarif (Pay as you go) umgestellt haben, klicken Sie auf Upgraden, um dies zu tun. Sie werden nur dann zum Upgraden aufgefordert, wenn Ihr Projekt nicht im Blaze-Tarif ist.
Nur Projekte mit dem Blaze-Tarif können cloudbasierte APIs verwenden.
- Wenn cloudbasierte APIs noch nicht aktiviert sind, klicken Sie auf Cloudbasierte APIs aktivieren.
Jetzt können Sie Bilder labeln.
1. Eingabebild vorbereiten
Erstellen Sie einFirebaseVisionImage
-Objekt aus Ihrem Bild.
Die Bildkennzeichnung funktioniert am schnellsten, wenn Sie ein Bitmap
verwenden. Wenn Sie die Camera2 API verwenden, empfiehlt sich ein JPEG-formatiertes media.Image
.
-
Wenn Sie ein
FirebaseVisionImage
-Objekt aus einemmedia.Image
-Objekt erstellen möchten, z. B. wenn Sie ein Bild mit der Kamera eines Geräts aufnehmen, übergeben Sie dasmedia.Image
-Objekt und die Drehung des Bildes anFirebaseVisionImage.fromMediaImage()
.Wenn Sie die CameraX-Bibliothek verwenden, berechnen die Klassen
OnImageCapturedListener
undImageAnalysis.Analyzer
den Rotationswert für Sie. Sie müssen die Rotation also nur in eine derROTATION_
-Konstanten von Firebase ML konvertieren, bevor SieFirebaseVisionImage.fromMediaImage()
aufrufen:Kotlin
private class YourImageAnalyzer : ImageAnalysis.Analyzer { private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) { 0 -> FirebaseVisionImageMetadata.ROTATION_0 90 -> FirebaseVisionImageMetadata.ROTATION_90 180 -> FirebaseVisionImageMetadata.ROTATION_180 270 -> FirebaseVisionImageMetadata.ROTATION_270 else -> throw Exception("Rotation must be 0, 90, 180, or 270.") } override fun analyze(imageProxy: ImageProxy?, degrees: Int) { val mediaImage = imageProxy?.image val imageRotation = degreesToFirebaseRotation(degrees) if (mediaImage != null) { val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation) // Pass image to an ML Vision API // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { private int degreesToFirebaseRotation(int degrees) { switch (degrees) { case 0: return FirebaseVisionImageMetadata.ROTATION_0; case 90: return FirebaseVisionImageMetadata.ROTATION_90; case 180: return FirebaseVisionImageMetadata.ROTATION_180; case 270: return FirebaseVisionImageMetadata.ROTATION_270; default: throw new IllegalArgumentException( "Rotation must be 0, 90, 180, or 270."); } } @Override public void analyze(ImageProxy imageProxy, int degrees) { if (imageProxy == null || imageProxy.getImage() == null) { return; } Image mediaImage = imageProxy.getImage(); int rotation = degreesToFirebaseRotation(degrees); FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation); // Pass image to an ML Vision API // ... } }
Wenn Sie keine Kamerabibliothek verwenden, die die Drehung des Bildes angibt, können Sie sie aus der Drehung des Geräts und der Ausrichtung des Kamerasensors im Gerät berechnen:
Kotlin
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 90) ORIENTATIONS.append(Surface.ROTATION_90, 0) ORIENTATIONS.append(Surface.ROTATION_180, 270) ORIENTATIONS.append(Surface.ROTATION_270, 180) } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Throws(CameraAccessException::class) private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. val deviceRotation = activity.windowManager.defaultDisplay.rotation var rotationCompensation = ORIENTATIONS.get(deviceRotation) // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360 // Return the corresponding FirebaseVisionImageMetadata rotation value. val result: Int when (rotationCompensation) { 0 -> result = FirebaseVisionImageMetadata.ROTATION_0 90 -> result = FirebaseVisionImageMetadata.ROTATION_90 180 -> result = FirebaseVisionImageMetadata.ROTATION_180 270 -> result = FirebaseVisionImageMetadata.ROTATION_270 else -> { result = FirebaseVisionImageMetadata.ROTATION_0 Log.e(TAG, "Bad rotation value: $rotationCompensation") } } return result }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private int getRotationCompensation(String cameraId, Activity activity, Context context) throws CameraAccessException { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int rotationCompensation = ORIENTATIONS.get(deviceRotation); // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360; // Return the corresponding FirebaseVisionImageMetadata rotation value. int result; switch (rotationCompensation) { case 0: result = FirebaseVisionImageMetadata.ROTATION_0; break; case 90: result = FirebaseVisionImageMetadata.ROTATION_90; break; case 180: result = FirebaseVisionImageMetadata.ROTATION_180; break; case 270: result = FirebaseVisionImageMetadata.ROTATION_270; break; default: result = FirebaseVisionImageMetadata.ROTATION_0; Log.e(TAG, "Bad rotation value: " + rotationCompensation); } return result; }
Übergeben Sie dann das
media.Image
-Objekt und den Rotationswert anFirebaseVisionImage.fromMediaImage()
:Kotlin
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
- Wenn Sie ein
FirebaseVisionImage
-Objekt aus einem Datei-URI erstellen möchten, übergeben Sie den App-Kontext und den Datei-URI anFirebaseVisionImage.fromFilePath()
. Das ist nützlich, wenn Sie mit einemACTION_GET_CONTENT
-Intent den Nutzer auffordern, ein Bild aus seiner Galerie-App auszuwählen.Kotlin
val image: FirebaseVisionImage try { image = FirebaseVisionImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
FirebaseVisionImage image; try { image = FirebaseVisionImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
- Wenn Sie ein
FirebaseVisionImage
-Objekt aus einemByteBuffer
-Objekt oder einem Byte-Array erstellen möchten, berechnen Sie zuerst die Bilddrehung wie oben für diemedia.Image
-Eingabe beschrieben.Erstellen Sie dann ein
FirebaseVisionImageMetadata
-Objekt, das die Höhe, Breite, Farbcodierungsformat und Drehung des Bildes enthält:Kotlin
val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build()
Java
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build();
Erstellen Sie mit dem Puffer oder Array und dem Metadatenobjekt ein
FirebaseVisionImage
-Objekt:Kotlin
val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata) // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata); // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);
- So erstellen Sie ein
FirebaseVisionImage
-Objekt aus einemBitmap
-Objekt:Kotlin
val image = FirebaseVisionImage.fromBitmap(bitmap)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Bitmap
-Objekt dargestellt wird, muss aufrecht sein und darf nicht zusätzlich gedreht werden müssen.
2. Bildlabeler konfigurieren und ausführen
Wenn Sie Objekte in einem Bild mit Labels versehen möchten, übergeben Sie dasFirebaseVisionImage
-Objekt an die processImage
-Methode von FirebaseVisionImageLabeler
.
Rufen Sie zuerst eine Instanz von
FirebaseVisionImageLabeler
ab.Kotlin
val labeler = FirebaseVision.getInstance().getCloudImageLabeler() // Or, to set the minimum confidence required: // val options = FirebaseVisionCloudImageLabelerOptions.Builder() // .setConfidenceThreshold(0.7f) // .build() // val labeler = FirebaseVision.getInstance().getCloudImageLabeler(options)
Java
FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance() .getCloudImageLabeler(); // Or, to set the minimum confidence required: // FirebaseVisionCloudImageLabelerOptions options = // new FirebaseVisionCloudImageLabelerOptions.Builder() // .setConfidenceThreshold(0.7f) // .build(); // FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance() // .getCloudImageLabeler(options);
Übergeben Sie das Bild dann an die
processImage()
-Methode:Kotlin
labeler.processImage(image) .addOnSuccessListener { labels -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Java
labeler.processImage(image) .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionImageLabel>>() { @Override public void onSuccess(List<FirebaseVisionImageLabel> labels) { // Task completed successfully // ... } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
3. Informationen zu gekennzeichneten Objekten abrufen
Wenn die Bildkennzeichnung erfolgreich ist, wird eine Liste vonFirebaseVisionImageLabel
-Objekten an den Erfolgslistener übergeben. Jedes FirebaseVisionImageLabel
-Objekt stellt etwas dar, das im Bild gekennzeichnet wurde. Für jedes Label können Sie die Textbeschreibung des Labels, die Knowledge Graph-Entitäts-ID (falls verfügbar) und den Konfidenzwert der Übereinstimmung abrufen. Beispiel:
Kotlin
for (label in labels) {
val text = label.text
val entityId = label.entityId
val confidence = label.confidence
}
Java
for (FirebaseVisionImageLabel label: labels) {
String text = label.getText();
String entityId = label.getEntityId();
float confidence = label.getConfidence();
}
Nächste Schritte
- Bevor Sie eine App, die eine Cloud API verwendet, in der Produktionsumgebung bereitstellen, sollten Sie einige zusätzliche Schritte unternehmen, um unbefugten API-Zugriff zu verhindern und die Auswirkungen zu minimieren.