Za pomocą systemów uczących się Firebase możesz rozpoznawać tekst na obrazach. Firebase ML ma zarówno ogólny interfejs API, który nadaje się do rozpoznawania tekstu na obrazach, takie jak tekst znaku drogowego, jak i interfejs API zoptymalizowany pod kątem rozpoznawania tekstu dokumentów.
Zanim zaczniesz
- Dodaj Firebase do swojego projektu na Androida, jeśli jeszcze go nie masz.
-
W pliku Gradle na poziomie modułu (na poziomie aplikacji) (zwykle
<project>/<app-module>/build.gradle.kts
lub<project>/<app-module>/build.gradle
) dodaj zależność do biblioteki Firebase ML Vision na Androida. Do kontrolowania obsługi wersji biblioteki zalecamy używanie BOM Firebase na Androida.dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:33.1.1")) // 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' }
Dzięki wykorzystaniu BM od Firebase Android Twoja aplikacja zawsze będzie używała zgodnych wersji bibliotek Firebase na Androida.
(Alternatywnie) Dodaj zależności biblioteki Firebase bez użycia BoM.
Jeśli nie chcesz używać BoM Firebase, musisz określić każdą wersję biblioteki Firebase w wierszu zależności.
Pamiętaj, że jeśli w aplikacji używasz wielu bibliotek Firebase, zdecydowanie zalecamy korzystanie z BoM do zarządzania wersjami biblioteki. Zapewni to zgodność wszystkich wersji.
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' }
-
Jeśli nie masz jeszcze włączonych w projekcie interfejsów API działających w chmurze, zrób to teraz:
- Otwórz stronę interfejsów API Firebase ML w konsoli Firebase.
-
Jeśli w swoim projekcie nie korzystasz jeszcze z abonamentu Blaze, kliknij Przejdź na wyższą wersję (prośbę o przejście na wyższą wersję otrzymasz tylko wtedy, gdy Twojego projektu nie ma w abonamencie Blaze).
Tylko projekty na poziomie Blaze mogą korzystać z interfejsów API działających w chmurze.
- Jeśli interfejsy API działające w chmurze nie są jeszcze włączone, kliknij Włącz interfejsy API działające w chmurze.
Teraz możesz zacząć rozpoznawać tekst na obrazach.
Wskazówki dotyczące obrazu wejściowego
-
Aby systemy uczące się Firebase mogły dokładnie rozpoznawać tekst, obrazy wejściowe muszą zawierać tekst reprezentowany przez wystarczającą ilość danych pikseli. Najlepiej, aby w przypadku tekstu łacińskiego każdy znak miał rozmiar co najmniej 16 x 16 pikseli. W przypadku tekstów w językach chińskim, japońskim i koreańskim każdy znak powinien mieć wymiary 24 × 24 piksele. W przypadku wszystkich języków zwykle nie ma zastosowania w dokładności w przypadku znaków większych niż 24 x 24 piksele.
Na przykład obraz o wymiarach 640 × 480 może sprawdzić się do skanowania wizytówki, która zajmuje całą szerokość obrazu. Do zeskanowania dokumentu wydrukowanego na papierze o rozmiarze literowym może być wymagany obraz o wymiarach 720 x 1280 pikseli.
-
Słaba ostrość obrazu może negatywnie wpłynąć na dokładność rozpoznawania tekstu. Jeśli wyniki nie są zadowalające, poproś użytkownika o ponowne zdjęcie obrazu.
Rozpoznawanie tekstu w obrazach
Aby rozpoznać tekst na obrazie, uruchom moduł rozpoznawania tekstu w sposób opisany poniżej.
1. Uruchom moduł rozpoznawania tekstu
Aby rozpoznać tekst na obrazie, utwórz obiektFirebaseVisionImage
z Bitmap
, media.Image
, ByteBuffer
, tablicy bajtów lub pliku na urządzeniu. Następnie przekaż obiekt FirebaseVisionImage
do metody processImage
metody FirebaseVisionTextRecognizer
.
Utwórz obiekt
FirebaseVisionImage
na podstawie obrazu.-
Aby utworzyć obiekt
FirebaseVisionImage
z obiektumedia.Image
, np. podczas robienia zdjęcia z aparatu urządzenia, przekaż obiektmedia.Image
i obrót obrazu do wartościFirebaseVisionImage.fromMediaImage()
.Jeśli używasz biblioteki KameraX, klasy
OnImageCapturedListener
iImageAnalysis.Analyzer
obliczają za Ciebie wartość rotacji, więc musisz tylko przekonwertować rotację na jedną ze stałychROTATION_
ML Firebase przed wywołaniemFirebaseVisionImage.fromMediaImage()
: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 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 // ... } }
Jeśli nie korzystasz z biblioteki aparatów, która określa obrót obrazu, możesz obliczyć tę wartość na podstawie obrotu urządzenia i orientacji czujnika aparatu:
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 }
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; }
Następnie przekaż obiekt
media.Image
i wartość rotacji doFirebaseVisionImage.fromMediaImage()
:Kotlin+KTX
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
- Aby utworzyć obiekt
FirebaseVisionImage
na podstawie identyfikatora URI pliku, przekaż kontekst aplikacji i identyfikator URI pliku doFirebaseVisionImage.fromFilePath()
. Jest to przydatne, gdy używasz intencjiACTION_GET_CONTENT
, aby prosić użytkownika o wybranie obrazu z aplikacji galerii.Kotlin+KTX
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(); }
- Aby utworzyć obiekt
FirebaseVisionImage
na podstawieByteBuffer
lub tablicy bajtów, najpierw oblicz obrót obrazu w sposób opisany powyżej dla danych wejściowychmedia.Image
.Następnie utwórz obiekt
FirebaseVisionImageMetadata
zawierający wysokość, szerokość, format kodowania kolorów i obrót obrazu: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()
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();
Użyj bufora lub tablicy i obiektu metadanych, aby utworzyć obiekt
FirebaseVisionImage
:Kotlin+KTX
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);
- Aby utworzyć obiekt
FirebaseVisionImage
z obiektuBitmap
:Kotlin+KTX
val image = FirebaseVisionImage.fromBitmap(bitmap)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Bitmap
musi być ustawiony pionowo i nie musi być dodatkowo obracany.
-
Pobrać wystąpienie obiektu
FirebaseVisionTextRecognizer
.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()
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();
Na koniec przekaż obraz do metody
processImage
:Kotlin+KTX
val result = detector.processImage(image) .addOnSuccessListener { firebaseVisionText -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
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 // ... } });
2. Wyodrębnianie tekstu z bloków rozpoznanego tekstu
Jeśli operacja rozpoznawania tekstu się powiedzie, do odbiornika zostanie przekazany obiektFirebaseVisionText
. Obiekt FirebaseVisionText
zawiera pełny tekst rozpoznawany na obrazie oraz zero lub więcej obiektów TextBlock
.
Każdy element TextBlock
reprezentuje prostokątny blok tekstu, który zawiera 0 lub więcej obiektów Line
. Każdy obiekt Line
zawiera 0 lub więcej obiektów Element
, które reprezentują słowa i encje słowne (daty, liczby itp.).
Dla każdego obiektu TextBlock
, Line
i Element
możesz otrzymać tekst rozpoznawany w regionie oraz jego współrzędne geograficzne.
Przykład:
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 } } }
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(); } } }
Dalsze kroki
- Zanim wdrożysz w środowisku produkcyjnym aplikację, która korzysta z interfejsu Cloud API, musisz wykonać dodatkowe czynności, aby zapobiegać i ograniczać skutki nieautoryzowanego dostępu do interfejsu API.
Rozpoznawanie tekstu na obrazach dokumentów
Aby rozpoznać tekst dokumentu, skonfiguruj i uruchom moduł rozpoznawania tekstu w sposób opisany poniżej.
Opisany poniżej interfejs API rozpoznawania tekstu dokumentów ma ułatwiać pracę z obrazami dokumentów. Jeśli jednak wolisz interfejs udostępniany przez interfejs API FirebaseVisionTextRecognizer
, możesz go używać do skanowania dokumentów. W tym celu skonfiguruj narzędzie do rozpoznawania tekstu w chmurze tak, aby używało modelu gęstego tekstu.
Aby użyć interfejsu API rozpoznawania tekstu w dokumentach:
1. Uruchom moduł rozpoznawania tekstu
Aby rozpoznać tekst na obrazie, utwórz obiektFirebaseVisionImage
z elementu Bitmap
, media.Image
, ByteBuffer
, tablicy bajtów lub pliku na urządzeniu.
Następnie przekaż obiekt FirebaseVisionImage
do metody processImage
metody FirebaseVisionDocumentTextRecognizer
.
Utwórz obiekt
FirebaseVisionImage
na podstawie obrazu.-
Aby utworzyć obiekt
FirebaseVisionImage
z obiektumedia.Image
, np. podczas robienia zdjęcia z aparatu urządzenia, przekaż obiektmedia.Image
i obrót obrazu do wartościFirebaseVisionImage.fromMediaImage()
.Jeśli używasz biblioteki KameraX, klasy
OnImageCapturedListener
iImageAnalysis.Analyzer
obliczają za Ciebie wartość rotacji, więc musisz tylko przekonwertować rotację na jedną ze stałychROTATION_
ML Firebase przed wywołaniemFirebaseVisionImage.fromMediaImage()
: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 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 // ... } }
Jeśli nie korzystasz z biblioteki aparatów, która określa obrót obrazu, możesz obliczyć tę wartość na podstawie obrotu urządzenia i orientacji czujnika aparatu:
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 }
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; }
Następnie przekaż obiekt
media.Image
i wartość rotacji doFirebaseVisionImage.fromMediaImage()
:Kotlin+KTX
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
- Aby utworzyć obiekt
FirebaseVisionImage
na podstawie identyfikatora URI pliku, przekaż kontekst aplikacji i identyfikator URI pliku doFirebaseVisionImage.fromFilePath()
. Jest to przydatne, gdy używasz intencjiACTION_GET_CONTENT
, aby prosić użytkownika o wybranie obrazu z aplikacji galerii.Kotlin+KTX
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(); }
- Aby utworzyć obiekt
FirebaseVisionImage
na podstawieByteBuffer
lub tablicy bajtów, najpierw oblicz obrót obrazu w sposób opisany powyżej dla danych wejściowychmedia.Image
.Następnie utwórz obiekt
FirebaseVisionImageMetadata
zawierający wysokość, szerokość, format kodowania kolorów i obrót obrazu: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()
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();
Użyj bufora lub tablicy i obiektu metadanych, aby utworzyć obiekt
FirebaseVisionImage
:Kotlin+KTX
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);
- Aby utworzyć obiekt
FirebaseVisionImage
z obiektuBitmap
:Kotlin+KTX
val image = FirebaseVisionImage.fromBitmap(bitmap)
Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Bitmap
musi być ustawiony pionowo i nie musi być dodatkowo obracany.
-
Pobierz wystąpienie
FirebaseVisionDocumentTextRecognizer
: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)
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);
Na koniec przekaż obraz do metody
processImage
:Kotlin+KTX
detector.processImage(myImage) .addOnSuccessListener { firebaseVisionDocumentText -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
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 // ... } });
2. Wyodrębnianie tekstu z bloków rozpoznanego tekstu
Jeśli operacja rozpoznawania tekstu się powiedzie, zwróci obiekt FirebaseVisionDocumentText
. Obiekt FirebaseVisionDocumentText
zawiera pełny tekst rozpoznawany na obrazie oraz hierarchię obiektów, która odzwierciedla strukturę rozpoznanego dokumentu:
FirebaseVisionDocumentText.Block
FirebaseVisionDocumentText.Paragraph
FirebaseVisionDocumentText.Word
FirebaseVisionDocumentText.Symbol
W przypadku każdego obiektu Block
, Paragraph
, Word
i Symbol
można uzyskać tekst rozpoznawany w regionie i jego współrzędne graniczne.
Przykład:
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 } } } }
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(); } } } }
Dalsze kroki
- Zanim wdrożysz w środowisku produkcyjnym aplikację, która korzysta z interfejsu Cloud API, musisz wykonać dodatkowe czynności, aby zapobiegać i ograniczać skutki nieautoryzowanego dostępu do interfejsu API.