Google is committed to advancing racial equity for Black communities. See how.
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Erkennen Sie Text in Bildern mit ML Kit auf Android

Sie können ML Kit verwenden, um Text in Bildern zu erkennen. ML Kit verfügt sowohl über eine Allzweck-API, die zum Erkennen von Text in Bildern geeignet ist, z. B. den Text eines Straßenschilds, als auch über eine API, die zum Erkennen des Textes von Dokumenten optimiert ist. Die Allzweck-API verfügt sowohl über Geräte- als auch über Cloud-basierte Modelle. Die Erkennung von Dokumenttexten ist nur als Cloud-basiertes Modell verfügbar. In der Übersicht finden Sie einen Vergleich der Cloud- und On-Device-Modelle.

Bevor Sie beginnen

  1. Wenn Sie dies noch nicht getan haben, fügen Sie Firebase zu Ihrem Android-Projekt hinzu .
  2. build.gradle in Ihrer build.gradle Datei auf Projektebene sicher, dass das Maven-Repository von Google sowohl in Ihrem buildscript als auch in Ihrem allprojects Abschnitt enthalten ist.
  3. Fügen Sie die Abhängigkeiten für die ML Kit Android-Bibliotheken zu Ihrer Gradle-Datei (normalerweise app/build.gradle ) Ihres Moduls (App-Ebene) app/build.gradle :
    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies {
      // ...
    
      implementation 'com.google.firebase:firebase-ml-vision:24.0.3'
    }
    
  4. Optional, aber empfohlen : Wenn Sie die API auf dem Gerät verwenden, konfigurieren Sie Ihre App so, dass das ML-Modell nach der Installation Ihrer App aus dem Play Store automatisch auf das Gerät heruntergeladen wird.

    AndroidManifest.xml Sie dazu der AndroidManifest.xml Datei Ihrer App die folgende Deklaration AndroidManifest.xml :

    <application ...>
      ...
      <meta-data
          android:name="com.google.firebase.ml.vision.DEPENDENCIES"
          android:value="ocr" />
      <!-- To use multiple models: android:value="ocr,model2,model3" -->
    </application>
    
    Wenn Sie das Herunterladen von Modellen zur Installationszeit nicht aktivieren, wird das Modell beim ersten Ausführen des Detektors auf dem Gerät heruntergeladen. Anfragen, die Sie vor Abschluss des Downloads stellen, führen zu keinen Ergebnissen.
  5. Wenn Sie das Cloud-basierte Modell verwenden möchten und die Cloud-basierten APIs für Ihr Projekt noch nicht aktiviert haben, gehen Sie jetzt wie folgt vor:

    1. Öffnen Sie die Seite ML Kit APIs der Firebase-Konsole.
    2. Wenn Sie Ihr Projekt noch nicht auf einen Blaze-Plan aktualisiert haben, klicken Sie dazu auf Aktualisieren . (Sie werden nur dann zum Upgrade aufgefordert, wenn Ihr Projekt nicht im Blaze-Plan enthalten ist.)

      Nur Blaze-Projekte können Cloud-basierte APIs verwenden.

    3. Wenn Cloud-basierte APIs noch nicht aktiviert sind, klicken Sie auf Cloud-basierte APIs aktivieren.

    Wenn Sie nur das Gerätemodell verwenden möchten, können Sie diesen Schritt überspringen.

Jetzt können Sie Text in Bildern erkennen.

Bildrichtlinien eingeben

  • Damit ML Kit Text genau erkennt, müssen Eingabebilder Text enthalten, der durch ausreichende Pixeldaten dargestellt wird. Idealerweise sollte für lateinischen Text jedes Zeichen mindestens 16 x 16 Pixel groß sein. Für chinesischen, japanischen und koreanischen Text (nur von den Cloud-basierten APIs unterstützt) sollte jedes Zeichen 24 x 24 Pixel groß sein. Für alle Sprachen gibt es im Allgemeinen keinen Genauigkeitsvorteil, wenn Zeichen größer als 24 x 24 Pixel sind.

    So kann beispielsweise ein 640 x 480-Bild gut zum Scannen einer Visitenkarte verwendet werden, die die gesamte Bildbreite einnimmt. Zum Scannen eines auf Papier im Letter-Format gedruckten Dokuments ist möglicherweise ein Bild mit 720 x 1280 Pixel erforderlich.

  • Ein schlechter Bildfokus kann die Genauigkeit der Texterkennung beeinträchtigen. Wenn Sie keine akzeptablen Ergebnisse erhalten, bitten Sie den Benutzer, das Bild erneut zu erfassen.

  • Wenn Sie Text in einer Echtzeitanwendung erkennen, möchten Sie möglicherweise auch die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Um die Latenz zu verringern, erfassen Sie Bilder mit niedrigeren Auflösungen (unter Berücksichtigung der oben genannten Genauigkeitsanforderungen) und stellen Sie sicher, dass der Text so viel Bild wie möglich einnimmt. Siehe auch Tipps zur Verbesserung der Echtzeitleistung .


Erkennen Sie Text in Bildern

Führen Sie die Texterkennung wie unten beschrieben aus, um Text in einem Bild mithilfe eines geräte- oder cloudbasierten Modells zu erkennen.

1. Führen Sie die Texterkennung aus

Um Text in einem Bild zu erkennen, erstellen Sie ein FirebaseVisionImage Objekt entweder aus einer Bitmap , einem media.Image , einem ByteBuffer , einem Byte-Array oder einer Datei auf dem Gerät. Dann passiert das FirebaseVisionImage Objekt des FirebaseVisionTextRecognizer ‚s processImage Methode.

  1. Erstellen Sie ein FirebaseVisionImage Objekt aus Ihrem Bild.

    • Um ein FirebaseVisionImage Objekt aus einem media.Image Objekt zu erstellen, z. B. beim media.Image eines Bildes von der Kamera eines Geräts, übergeben Sie das media.Image Objekt und die Drehung des Bildes an FirebaseVisionImage.fromMediaImage() .

      Wenn Sie die CameraX- Bibliothek verwenden, berechnen die Klassen OnImageCapturedListener und ImageAnalysis.Analyzer den Rotationswert für Sie. Sie müssen die Rotation also nur in eine der ROTATION_ Konstanten von ML Kit ROTATION_ bevor Sie FirebaseVisionImage.fromMediaImage() aufrufen:

      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 Kit Vision API
              // ...
          }
      }
      

      Kotlin + KTX

      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 Kit Vision API
                  // ...
              }
          }
      }
      

      Wenn Sie keine Kamerabibliothek verwenden, die die Bilddrehung angibt, können Sie diese aus der Drehung des Geräts und der Ausrichtung des Kamerasensors im Gerät berechnen:

      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;
      }

      Kotlin + KTX

      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
      }

      media.Image dann das media.Image Objekt und den Rotationswert an FirebaseVisionImage.fromMediaImage() :

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);

      Kotlin + KTX

      val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
    • FirebaseVisionImage zum Erstellen eines FirebaseVisionImage Objekts aus einem Datei-URI den App-Kontext und den Datei-URI an FirebaseVisionImage.fromFilePath() . Dies ist nützlich, wenn Sie eine ACTION_GET_CONTENT Absicht verwenden, um den Benutzer ACTION_GET_CONTENT , ein Bild aus seiner Galerie-App auszuwählen.

      Java

      FirebaseVisionImage image;
      try {
          image = FirebaseVisionImage.fromFilePath(context, uri);
      } catch (IOException e) {
          e.printStackTrace();
      }

      Kotlin + KTX

      val image: FirebaseVisionImage
      try {
          image = FirebaseVisionImage.fromFilePath(context, uri)
      } catch (e: IOException) {
          e.printStackTrace()
      }
    • Um ein FirebaseVisionImage Objekt aus einem ByteBuffer oder einem Byte-Array zu erstellen, berechnen Sie zunächst die media.Image wie oben für media.Image Eingabe von media.Image .

      Erstellen Sie dann ein FirebaseVisionImageMetadata Objekt, das die Höhe, Breite, das Farbcodierungsformat und die Drehung des Bildes enthält:

      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();

      Kotlin + KTX

      val metadata = FirebaseVisionImageMetadata.Builder()
              .setWidth(480) // 480x360 is typically sufficient for
              .setHeight(360) // image recognition
              .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
              .setRotation(rotation)
              .build()

      Verwenden Sie den Puffer oder das Array und das Metadatenobjekt, um ein FirebaseVisionImage Objekt zu erstellen:

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata);
      // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);

      Kotlin + KTX

      val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata)
      // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
    • So erstellen Sie ein FirebaseVisionImage Objekt aus einem Bitmap Objekt:

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);

      Kotlin + KTX

      val image = FirebaseVisionImage.fromBitmap(bitmap)
      Das vom Bitmap Objekt dargestellte Bild muss aufrecht sein, ohne dass eine zusätzliche Drehung erforderlich ist.

  2. FirebaseVisionTextRecognizer Sie eine Instanz von FirebaseVisionTextRecognizer .

    So verwenden Sie das Gerätemodell:

    Java

    FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance()
            .getOnDeviceTextRecognizer();

    Kotlin + KTX

    val detector = FirebaseVision.getInstance()
            .onDeviceTextRecognizer

    So verwenden Sie das Cloud-basierte Modell:

    Java

    FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance()
            .getCloudTextRecognizer();
    // Or, to change the default settings:
    //   FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance()
    //          .getCloudTextRecognizer(options);
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    FirebaseVisionCloudTextRecognizerOptions options = new FirebaseVisionCloudTextRecognizerOptions.Builder()
            .setLanguageHints(Arrays.asList("en", "hi"))
            .build();
    

    Kotlin + KTX

    val detector = FirebaseVision.getInstance().cloudTextRecognizer
    // Or, to change the default settings:
    // val detector = FirebaseVision.getInstance().getCloudTextRecognizer(options)
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    val options = FirebaseVisionCloudTextRecognizerOptions.Builder()
            .setLanguageHints(listOf("en", "hi"))
            .build()
    
  3. processImage das Bild schließlich an die processImage Methode:

    Java

    Task<FirebaseVisionText> result =
            detector.processImage(image)
                    .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
                        @Override
                        public void onSuccess(FirebaseVisionText firebaseVisionText) {
                            // Task completed successfully
                            // ...
                        }
                    })
                    .addOnFailureListener(
                            new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    // Task failed with an exception
                                    // ...
                                }
                            });

    Kotlin + KTX

    val result = detector.processImage(image)
            .addOnSuccessListener { firebaseVisionText ->
                // Task completed successfully
                // ...
            }
            .addOnFailureListener { e ->
                // Task failed with an exception
                // ...
            }

2. Extrahieren Sie Text aus Blöcken erkannten Textes

Wenn die Texterkennung erfolgreich ist, wird ein FirebaseVisionText Objekt an den Erfolgslistener übergeben. Ein FirebaseVisionText Objekt enthält den im Bild erkannten Volltext und null oder mehr TextBlock Objekte.

Jeder TextBlock darstellt , einen rechteckigen Block von Text, der enthält null oder mehr Line Jede Line Objekt enthält null oder mehr Element - Objekte, die repräsentieren Worte und Wort wie Entitäten (Daten, Zahlen, und so weiter).

Für jeden TextBlock , Line und Element - Objekt, können Sie den Text in der Region und die begrenzenden Koordinaten der Region anerkannt bekommen.

Beispielsweise:

Java

String resultText = result.getText();
for (FirebaseVisionText.TextBlock block: result.getTextBlocks()) {
    String blockText = block.getText();
    Float blockConfidence = block.getConfidence();
    List<RecognizedLanguage> blockLanguages = block.getRecognizedLanguages();
    Point[] blockCornerPoints = block.getCornerPoints();
    Rect blockFrame = block.getBoundingBox();
    for (FirebaseVisionText.Line line: block.getLines()) {
        String lineText = line.getText();
        Float lineConfidence = line.getConfidence();
        List<RecognizedLanguage> lineLanguages = line.getRecognizedLanguages();
        Point[] lineCornerPoints = line.getCornerPoints();
        Rect lineFrame = line.getBoundingBox();
        for (FirebaseVisionText.Element element: line.getElements()) {
            String elementText = element.getText();
            Float elementConfidence = element.getConfidence();
            List<RecognizedLanguage> elementLanguages = element.getRecognizedLanguages();
            Point[] elementCornerPoints = element.getCornerPoints();
            Rect elementFrame = element.getBoundingBox();
        }
    }
}

Kotlin + KTX

val resultText = result.text
for (block in result.textBlocks) {
    val blockText = block.text
    val blockConfidence = block.confidence
    val blockLanguages = block.recognizedLanguages
    val blockCornerPoints = block.cornerPoints
    val blockFrame = block.boundingBox
    for (line in block.lines) {
        val lineText = line.text
        val lineConfidence = line.confidence
        val lineLanguages = line.recognizedLanguages
        val lineCornerPoints = line.cornerPoints
        val lineFrame = line.boundingBox
        for (element in line.elements) {
            val elementText = element.text
            val elementConfidence = element.confidence
            val elementLanguages = element.recognizedLanguages
            val elementCornerPoints = element.cornerPoints
            val elementFrame = element.boundingBox
        }
    }
}

Tipps zur Verbesserung der Echtzeitleistung

Wenn Sie das Gerätemodell verwenden möchten, um Text in einer Echtzeitanwendung zu erkennen, befolgen Sie diese Richtlinien, um die besten Frameraten zu erzielen:

  • Gasaufrufe an die Texterkennung. Wenn ein neues Videobild verfügbar wird, während die Texterkennung ausgeführt wird, lassen Sie das Bild fallen.
  • Wenn Sie die Ausgabe des Texterkenners verwenden, um Grafiken auf dem Eingabebild zu überlagern, rufen Sie zuerst das Ergebnis von ML Kit ab, rendern Sie dann das Bild und überlagern Sie es in einem einzigen Schritt. Auf diese Weise rendern Sie für jeden Eingaberahmen nur einmal auf die Anzeigeoberfläche.
  • Wenn Sie die Camera2-API verwenden, erfassen Sie Bilder im Format ImageFormat.YUV_420_888 .

    Wenn Sie die ältere Kamera-API verwenden, erfassen Sie Bilder im ImageFormat.NV21 Format.

  • Erwägen Sie die Aufnahme von Bildern mit einer niedrigeren Auflösung. Beachten Sie jedoch auch die Anforderungen an die Bilddimension dieser API.

Nächste Schritte


Erkennen Sie Text in Bildern von Dokumenten

Um den Text eines Dokuments zu erkennen, konfigurieren Sie den Cloud-basierten Dokumenttexterkenner wie unten beschrieben und führen Sie ihn aus.

Die unten beschriebene API zur Erkennung von Dokumententexten bietet eine Schnittstelle, die für die Arbeit mit Bildern von Dokumenten bequemer sein soll. Wenn Sie jedoch die von der FirebaseVisionTextRecognizer API bereitgestellte Schnittstelle bevorzugen, können Sie sie stattdessen zum Scannen von Dokumenten verwenden, indem Sie den Cloud-Texterkenner für die Verwendung des dichten Textmodells konfigurieren.

So verwenden Sie die Dokumenttexterkennungs-API:

1. Führen Sie die Texterkennung aus

Um Text in einem Bild zu erkennen, erstellen Sie ein FirebaseVisionImage Objekt entweder aus einer Bitmap , einem media.Image , einem ByteBuffer , einem Byte-Array oder einer Datei auf dem Gerät. Dann passiert das FirebaseVisionImage Objekt des FirebaseVisionDocumentTextRecognizer ‚s processImage Methode.

  1. Erstellen Sie ein FirebaseVisionImage Objekt aus Ihrem Bild.

    • Um ein FirebaseVisionImage Objekt aus einem media.Image Objekt zu erstellen, z. B. beim media.Image eines Bildes von der Kamera eines Geräts, übergeben Sie das media.Image Objekt und die Drehung des Bildes an FirebaseVisionImage.fromMediaImage() .

      Wenn Sie die CameraX- Bibliothek verwenden, berechnen die Klassen OnImageCapturedListener und ImageAnalysis.Analyzer den Rotationswert für Sie. Sie müssen die Rotation also nur in eine der ROTATION_ Konstanten von ML Kit ROTATION_ bevor Sie FirebaseVisionImage.fromMediaImage() aufrufen:

      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 Kit Vision API
              // ...
          }
      }
      

      Kotlin + KTX

      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 Kit Vision API
                  // ...
              }
          }
      }
      

      Wenn Sie keine Kamerabibliothek verwenden, die die Bilddrehung angibt, können Sie diese aus der Drehung des Geräts und der Ausrichtung des Kamerasensors im Gerät berechnen:

      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;
      }

      Kotlin + KTX

      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
      }

      media.Image dann das media.Image Objekt und den Rotationswert an FirebaseVisionImage.fromMediaImage() :

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);

      Kotlin + KTX

      val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
    • FirebaseVisionImage zum Erstellen eines FirebaseVisionImage Objekts aus einem Datei-URI den App-Kontext und den Datei-URI an FirebaseVisionImage.fromFilePath() . Dies ist nützlich, wenn Sie eine ACTION_GET_CONTENT Absicht verwenden, um den Benutzer ACTION_GET_CONTENT , ein Bild aus seiner Galerie-App auszuwählen.

      Java

      FirebaseVisionImage image;
      try {
          image = FirebaseVisionImage.fromFilePath(context, uri);
      } catch (IOException e) {
          e.printStackTrace();
      }

      Kotlin + KTX

      val image: FirebaseVisionImage
      try {
          image = FirebaseVisionImage.fromFilePath(context, uri)
      } catch (e: IOException) {
          e.printStackTrace()
      }
    • Um ein FirebaseVisionImage Objekt aus einem ByteBuffer oder einem Byte-Array zu erstellen, berechnen Sie zunächst die media.Image wie oben für media.Image Eingabe von media.Image .

      Erstellen Sie dann ein FirebaseVisionImageMetadata Objekt, das die Höhe, Breite, das Farbcodierungsformat und die Drehung des Bildes enthält:

      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();

      Kotlin + KTX

      val metadata = FirebaseVisionImageMetadata.Builder()
              .setWidth(480) // 480x360 is typically sufficient for
              .setHeight(360) // image recognition
              .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
              .setRotation(rotation)
              .build()

      Verwenden Sie den Puffer oder das Array und das Metadatenobjekt, um ein FirebaseVisionImage Objekt zu erstellen:

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata);
      // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);

      Kotlin + KTX

      val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata)
      // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
    • So erstellen Sie ein FirebaseVisionImage Objekt aus einem Bitmap Objekt:

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);

      Kotlin + KTX

      val image = FirebaseVisionImage.fromBitmap(bitmap)
      Das vom Bitmap Objekt dargestellte Bild muss aufrecht sein, ohne dass eine zusätzliche Drehung erforderlich ist.

  2. FirebaseVisionDocumentTextRecognizer Sie eine Instanz von FirebaseVisionDocumentTextRecognizer :

    Java

    FirebaseVisionDocumentTextRecognizer detector = FirebaseVision.getInstance()
            .getCloudDocumentTextRecognizer();
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    FirebaseVisionCloudDocumentRecognizerOptions options =
            new FirebaseVisionCloudDocumentRecognizerOptions.Builder()
                    .setLanguageHints(Arrays.asList("en", "hi"))
                    .build();
    FirebaseVisionDocumentTextRecognizer detector = FirebaseVision.getInstance()
            .getCloudDocumentTextRecognizer(options);

    Kotlin + KTX

    val detector = FirebaseVision.getInstance()
            .cloudDocumentTextRecognizer
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    val options = FirebaseVisionCloudDocumentRecognizerOptions.Builder()
            .setLanguageHints(listOf("en", "hi"))
            .build()
    val detector = FirebaseVision.getInstance()
            .getCloudDocumentTextRecognizer(options)

  3. processImage das Bild schließlich an die processImage Methode:

    Java

    detector.processImage(myImage)
            .addOnSuccessListener(new OnSuccessListener<FirebaseVisionDocumentText>() {
                @Override
                public void onSuccess(FirebaseVisionDocumentText result) {
                    // Task completed successfully
                    // ...
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    // Task failed with an exception
                    // ...
                }
            });

    Kotlin + KTX

    detector.processImage(myImage)
            .addOnSuccessListener { firebaseVisionDocumentText ->
                // Task completed successfully
                // ...
            }
            .addOnFailureListener { e ->
                // Task failed with an exception
                // ...
            }

2. Extrahieren Sie Text aus Blöcken erkannten Textes

Wenn die Texterkennung erfolgreich ist, wird ein FirebaseVisionDocumentText Objekt zurückgegeben. Ein FirebaseVisionDocumentText Objekt enthält den im Bild erkannten Volltext und eine Hierarchie von Objekten, die die Struktur des erkannten Dokuments widerspiegeln:

Für jedes Block , Paragraph , Word und Symbol können Sie den in der Region erkannten Text und die Begrenzungskoordinaten der Region abrufen.

Beispielsweise:

Java

String resultText = result.getText();
for (FirebaseVisionDocumentText.Block block: result.getBlocks()) {
    String blockText = block.getText();
    Float blockConfidence = block.getConfidence();
    List<RecognizedLanguage> blockRecognizedLanguages = block.getRecognizedLanguages();
    Rect blockFrame = block.getBoundingBox();
    for (FirebaseVisionDocumentText.Paragraph paragraph: block.getParagraphs()) {
        String paragraphText = paragraph.getText();
        Float paragraphConfidence = paragraph.getConfidence();
        List<RecognizedLanguage> paragraphRecognizedLanguages = paragraph.getRecognizedLanguages();
        Rect paragraphFrame = paragraph.getBoundingBox();
        for (FirebaseVisionDocumentText.Word word: paragraph.getWords()) {
            String wordText = word.getText();
            Float wordConfidence = word.getConfidence();
            List<RecognizedLanguage> wordRecognizedLanguages = word.getRecognizedLanguages();
            Rect wordFrame = word.getBoundingBox();
            for (FirebaseVisionDocumentText.Symbol symbol: word.getSymbols()) {
                String symbolText = symbol.getText();
                Float symbolConfidence = symbol.getConfidence();
                List<RecognizedLanguage> symbolRecognizedLanguages = symbol.getRecognizedLanguages();
                Rect symbolFrame = symbol.getBoundingBox();
            }
        }
    }
}

Kotlin + KTX

val resultText = result.text
for (block in result.blocks) {
    val blockText = block.text
    val blockConfidence = block.confidence
    val blockRecognizedLanguages = block.recognizedLanguages
    val blockFrame = block.boundingBox
    for (paragraph in block.paragraphs) {
        val paragraphText = paragraph.text
        val paragraphConfidence = paragraph.confidence
        val paragraphRecognizedLanguages = paragraph.recognizedLanguages
        val paragraphFrame = paragraph.boundingBox
        for (word in paragraph.words) {
            val wordText = word.text
            val wordConfidence = word.confidence
            val wordRecognizedLanguages = word.recognizedLanguages
            val wordFrame = word.boundingBox
            for (symbol in word.symbols) {
                val symbolText = symbol.text
                val symbolConfidence = symbol.confidence
                val symbolRecognizedLanguages = symbol.recognizedLanguages
                val symbolFrame = symbol.boundingBox
            }
        }
    }
}

Nächste Schritte