Resimlerdeki veya videolardaki metinleri (örneğin, videodaki sokak tabelası gibi. Bu özelliğin temel özellikleri şunlardır:
Özellik | Gruplandırılmamış | Gruplandırılanlar |
---|---|---|
Kütüphanenin adı | com.google.android.gms:play-services-mlkit-text-recognition
com.google.android.gms:play-services-mlkit-text-recognition-chinese com.google.android.gms:play-services-mlkit-text-recognition-devanagari com.google.android.gms:play-services-mlkit-text-recognition-japanese com.google.android.gms:play-services-mlkit-text-recognition-korean |
com.google.mlkit:text-recognition
com.google.mlkit:text-recognition-chinese com.google.mlkit:text-recognition-devanagari com.google.mlkit:text-recognition-japanese com.google.mlkit:text-recognition-korean |
Uygulama | Model, Google Play Hizmetleri aracılığıyla dinamik olarak indirilir. | Model, derleme sırasında statik olarak uygulamanıza bağlıdır. |
Uygulama boyutu | Komut dosyası mimarisi başına yaklaşık 260 KB boyut artışı. | Her mimaride komut dosyası başına yaklaşık 4 MB boyut artışı. |
Başlatma süresi | İlk kullanımdan önce modelin indirilmesini beklemeniz gerekebilir. | Model hemen kullanılabilir. |
Performans | Çoğu cihazda Latin alfabesi kitaplığı için gerçek zamanlı, diğerleri için daha yavaştır. | Çoğu cihazda Latin alfabesi kitaplığı için gerçek zamanlı, diğerleri için daha yavaştır. |
Deneyin
- Örnek uygulamayı kullanarak bu API'nin örnek kullanımını inceleyin.
- Kodu, ile kendiniz deneyin codelab'e göz atın.
Başlamadan önce
- Proje düzeyindeki
build.gradle
dosyanıza, hembuildscript
hem deallprojects
bölümlerinize Google'ın Maven deposunu eklediğinizden emin olun. ML Kit Android kitaplıklarının bağımlılıklarını, modülünüzün uygulama düzeyindeki gradle dosyasına ekleyin. Bu dosya genellikle
app/build.gradle
türündedir:Modeli uygulamanızla gruplandırmak için:
dependencies { // To recognize Latin script implementation 'com.google.mlkit:text-recognition:16.0.1' // To recognize Chinese script implementation 'com.google.mlkit:text-recognition-chinese:16.0.1' // To recognize Devanagari script implementation 'com.google.mlkit:text-recognition-devanagari:16.0.1' // To recognize Japanese script implementation 'com.google.mlkit:text-recognition-japanese:16.0.1' // To recognize Korean script implementation 'com.google.mlkit:text-recognition-korean:16.0.1' }
Modeli Google Play Hizmetleri'nde kullanmak için:
dependencies { // To recognize Latin script implementation 'com.google.android.gms:play-services-mlkit-text-recognition:19.0.1' // To recognize Chinese script implementation 'com.google.android.gms:play-services-mlkit-text-recognition-chinese:16.0.1' // To recognize Devanagari script implementation 'com.google.android.gms:play-services-mlkit-text-recognition-devanagari:16.0.1' // To recognize Japanese script implementation 'com.google.android.gms:play-services-mlkit-text-recognition-japanese:16.0.1' // To recognize Korean script implementation 'com.google.android.gms:play-services-mlkit-text-recognition-korean:16.0.1' }
Modeli Google Play Hizmetleri'nde kullanmayı seçerseniz: uygulamanızı bu modele otomatik olarak indirecek şekilde yapılandırın Uygulamanızın Play Store'dan yüklendiğinden emin olun. Bunu yapmak için aşağıdakini ekleyin: beyanını uygulamanızın
AndroidManifest.xml
dosyasına ekleyin:<application ...> ... <meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="ocr" > <!-- To use multiple models: android:value="ocr,ocr_chinese,ocr_devanagari,ocr_japanese,ocr_korean,..." --> </application>
Ayrıca model kullanılabilirliğini açıkça kontrol edebilir ve Google Play hizmetleri ModuleLoadClient API üzerinden gönderebilirsiniz. Yükleme zamanı modelini etkinleştirmezseniz açıkça indirme isteğinde bulunduğunda, model ilk olarak indirilir. her zaman kapatın. İndirme işleminden önce yaptığınız istekler hiçbir sonuç döndürülmez.
1. TextRecognizer
örneği oluşturun
Seçenekleri ileterek bir TextRecognizer
örneği oluşturun
yukarıda bağımlı olduğunu beyan ettiğiniz kitaplıkla ilgili:
Kotlin
// When using Latin script library val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS) // When using Chinese script library val recognizer = TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build()) // When using Devanagari script library val recognizer = TextRecognition.getClient(DevanagariTextRecognizerOptions.Builder().build()) // When using Japanese script library val recognizer = TextRecognition.getClient(JapaneseTextRecognizerOptions.Builder().build()) // When using Korean script library val recognizer = TextRecognition.getClient(KoreanTextRecognizerOptions.Builder().build())
Java
// When using Latin script library TextRecognizer recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS); // When using Chinese script library TextRecognizer recognizer = TextRecognition.getClient(new ChineseTextRecognizerOptions.Builder().build()); // When using Devanagari script library TextRecognizer recognizer = TextRecognition.getClient(new DevanagariTextRecognizerOptions.Builder().build()); // When using Japanese script library TextRecognizer recognizer = TextRecognition.getClient(new JapaneseTextRecognizerOptions.Builder().build()); // When using Korean script library TextRecognizer recognizer = TextRecognition.getClient(new KoreanTextRecognizerOptions.Builder().build());
2. Giriş resmini hazırlama
Bir resimdeki metni tanımak için şuradan bir InputImage
nesnesi oluşturun:
Bitmap
, media.Image
, ByteBuffer
, bayt dizisi veya
olanak tanır. Ardından InputImage
nesnesini
TextRecognizer
adlı kullanıcının processImage
yöntemi.
InputImage
oluşturabilirsiniz
her biri aşağıda açıklanmıştır.
media.Image
kullanarak
InputImage
oluşturmak için
media.Image
nesnesinden bir nesneden (örneğin,
cihazın kamerasını, media.Image
nesnesini ve resmin
InputImage.fromMediaImage()
değerine döndürülüyor.
URL'yi
CameraX kitaplığı, OnImageCapturedListener
ve
ImageAnalysis.Analyzer
sınıfları rotasyon değerini hesaplar
sizin için.
Kotlin
private class YourImageAnalyzer : ImageAnalysis.Analyzer { override fun analyze(imageProxy: ImageProxy) { val mediaImage = imageProxy.image if (mediaImage != null) { val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) // Pass image to an ML Kit Vision API // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { @Override public void analyze(ImageProxy imageProxy) { Image mediaImage = imageProxy.getImage(); if (mediaImage != null) { InputImage image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees()); // Pass image to an ML Kit Vision API // ... } } }
Resmin dönme derecesini sağlayan bir kamera kitaplığı kullanmıyorsanız cihazın dönüş derecesinden ve kameranın yönünden hesaplayabilir cihazdaki sensör:
Kotlin
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 0) ORIENTATIONS.append(Surface.ROTATION_90, 90) ORIENTATIONS.append(Surface.ROTATION_180, 180) ORIENTATIONS.append(Surface.ROTATION_270, 270) } /** * 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, isFrontFacing: Boolean): 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) // Get the device's sensor orientation. val cameraManager = activity.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! if (isFrontFacing) { rotationCompensation = (sensorOrientation + rotationCompensation) % 360 } else { // back-facing rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360 } return rotationCompensation }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 0); ORIENTATIONS.append(Surface.ROTATION_90, 90); ORIENTATIONS.append(Surface.ROTATION_180, 180); ORIENTATIONS.append(Surface.ROTATION_270, 270); } /** * 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, boolean isFrontFacing) 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); // Get the device's sensor orientation. CameraManager cameraManager = (CameraManager) activity.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); if (isFrontFacing) { rotationCompensation = (sensorOrientation + rotationCompensation) % 360; } else { // back-facing rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360; } return rotationCompensation; }
Ardından, media.Image
nesnesini ve
döndürme derecesi değerini InputImage.fromMediaImage()
değerine ayarlayın:
Kotlin
val image = InputImage.fromMediaImage(mediaImage, rotation)
Java
InputImage image = InputImage.fromMediaImage(mediaImage, rotation);
Dosya URI'si kullanarak
InputImage
oluşturmak için
uygulama bağlamını ve dosya URI'sini
InputImage.fromFilePath()
. Bu özellik,
kullanıcıdan seçim yapmasını istemek için bir ACTION_GET_CONTENT
niyeti kullanın
galeri uygulamasından bir resim.
Kotlin
val image: InputImage try { image = InputImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
InputImage image; try { image = InputImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
ByteBuffer
veya ByteArray
kullanarak
InputImage
oluşturmak için
bir ByteBuffer
veya ByteArray
nesnesinden alıp almayacaksanız önce resmi hesaplayın
media.Image
girişi için daha önce açıklandığı gibi dönme derecesi.
Ardından, arabellek veya diziyle InputImage
nesnesini, bu resmin
yükseklik, genişlik, renk kodlama biçimi ve döndürme derecesi:
Kotlin
val image = InputImage.fromByteBuffer( byteBuffer, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 ) // Or: val image = InputImage.fromByteArray( byteArray, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 )
Java
InputImage image = InputImage.fromByteBuffer(byteBuffer, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 ); // Or: InputImage image = InputImage.fromByteArray( byteArray, /* image width */480, /* image height */360, rotation, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 );
Bitmap
kullanarak
InputImage
oluşturmak için
Bitmap
nesnesindeki şu bildirimi yapın:
Kotlin
val image = InputImage.fromBitmap(bitmap, 0)
Java
InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);
Resim, döndürme dereceleriyle birlikte bir Bitmap
nesnesiyle temsil edilir.
3. Resmi işleyin
Resmi process
yöntemine geçirin:
Kotlin
val result = recognizer.process(image) .addOnSuccessListener { visionText -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Java
Task<Text> result = recognizer.process(image) .addOnSuccessListener(new OnSuccessListener<Text>() { @Override public void onSuccess(Text visionText) { // Task completed successfully // ... } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
4. Tanınan metin bloklarındaki metni ayıkla
Metin tanıma işlemi başarılı olursa şuraya bir Text
nesnesi iletilir
yardımcı olur. Text
nesnesi, şurada tanınan tam metni içerir:
resim ve sıfır veya daha fazla TextBlock
nesne.
Her TextBlock
, dikdörtgen bir metin bloğunu temsil eder.
içeren bir Line
nesne. Her biri
Line
nesnesi, sıfır içeren bir metin satırını temsil eder
veya daha fazla Element
nesne kullanın. Her bir Element
nesne, bir kelimeyi veya sıfır ya da daha fazla içeren kelime benzeri bir varlığı temsil eder
Symbol
nesne algılandı. Her bir Symbol
nesne bir karakteri, rakamı veya kelime benzeri bir varlığı temsil eder.
Her bir TextBlock
, Line
için,
Element
ve Symbol
nesnesini görürseniz siz
bölgede tanınan metni, bölgenin sınırlayıcı koordinatlarını
bölgesi ve rotasyon bilgileri, güven puanı gibi diğer birçok
vb.
Örneğin:
Kotlin
val resultText = result.text for (block in result.textBlocks) { val blockText = block.text val blockCornerPoints = block.cornerPoints val blockFrame = block.boundingBox for (line in block.lines) { val lineText = line.text val lineCornerPoints = line.cornerPoints val lineFrame = line.boundingBox for (element in line.elements) { val elementText = element.text val elementCornerPoints = element.cornerPoints val elementFrame = element.boundingBox } } }
Java
String resultText = result.getText(); for (Text.TextBlock block : result.getTextBlocks()) { String blockText = block.getText(); Point[] blockCornerPoints = block.getCornerPoints(); Rect blockFrame = block.getBoundingBox(); for (Text.Line line : block.getLines()) { String lineText = line.getText(); Point[] lineCornerPoints = line.getCornerPoints(); Rect lineFrame = line.getBoundingBox(); for (Text.Element element : line.getElements()) { String elementText = element.getText(); Point[] elementCornerPoints = element.getCornerPoints(); Rect elementFrame = element.getBoundingBox(); for (Text.Symbol symbol : element.getSymbols()) { String symbolText = symbol.getText(); Point[] symbolCornerPoints = symbol.getCornerPoints(); Rect symbolFrame = symbol.getBoundingBox(); } } } }
Giriş resmi kuralları
-
Makine Öğrenimi Kiti'nin metni doğru bir şekilde tanıması için giriş resimlerinde yeterli piksel verisi ile temsil edilen metin. İdeal koşullarda her karakter en az 16x16 piksel olmalıdır. Genellikle herhangi bir daha doğru olması gerekir.
Bu nedenle, örneğin, 640x480 boyutunda bir resim, kartvizit taraması için iyi performans bir resim seçin. Üzerine yazdırılmış bir dokümanı taramak için büyük harf kullanıyorsanız 720x1280 piksel boyutunda bir resim gerekebilir.
-
Kötü resim odağı, metin tanıma doğruluğunu etkileyebilir. Uygun değilseniz kabul edilebilir sonuçlar alıyorsanız kullanıcıdan resmi yeniden çekmesini isteyin.
-
Gerçek zamanlı bir uygulamada metinleri tanıyorsanız, giriş resimlerinin genel boyutlarını göz önünde bulundurun. Daha küçük resimler daha hızlı işlenebilir. Gecikmeyi azaltmak için metnin mümkün olduğunca çok yer kapladığından emin olun ve görüntüleri daha düşük çözünürlüklerde yakalayın (doğruluğu unutmayın ve (yukarıda belirtilen gereksinimlere) uygun olacaktır. Daha fazla bilgi için bkz. Performansı iyileştirmeye yönelik ipuçları.
Performansı artırmaya yönelik ipuçları
- URL'yi
Camera
veyacamera2
API, algılayıcıya yapılan çağrıları kısıtlamaz. Yeni bir video ise çerçeve, algılayıcı çalışırken kullanılabilir hale gelirse çerçeveyi bırakın. Bkz. Örnek için hızlı başlangıç örnek uygulamasındakiVisionProcessorBase
sınıfı. CameraX
API'yi kullanıyorsanız karşı baskı stratejisinin varsayılan değerine ayarlandığından emin olunImageAnalysis.STRATEGY_KEEP_ONLY_LATEST
) Bu, aynı anda yalnızca bir resmin analiz için gönderilmesini garanti eder. Daha fazla resim üretilirse analiz aracı meşgulken üretilirse otomatik olarak bırakılır ve teslimat. Analiz edilen resim, çağırarak kapatıldıktan sonra ImageProxy.close(), bir sonraki en son resim gönderilir.- Algılayıcının çıkışını, üzerine grafik yerleştirmek için
giriş görüntüsünü kullanın, önce ML Kit'ten sonucu alın ve ardından görüntüyü oluşturun
tek bir adımda yapabilirsiniz. Bu, görüntü yüzeyine oluşturulur
her giriş karesi için yalnızca bir kez. Bkz.
CameraSourcePreview
ve Hızlı başlangıç örnek uygulamasındakiGraphicOverlay
sınıflarına göz atın. - Camera2 API'sini kullanıyorsanız görüntüleri şurada yakalayın:
ImageFormat.YUV_420_888
biçimindedir. Eski Kamera API'sini kullanıyorsanız görüntüleri şurada yakalayın:ImageFormat.NV21
biçimindedir. - Görüntüleri daha düşük çözünürlükte çekmeyi düşünün. Ancak unutmayın, resim boyutu şartlarına tabidir.