Görüntülerdeki metni tanımak için ML Kit'i kullanabilirsiniz. ML Kit, hem sokak tabelası metni gibi görüntülerdeki metni tanımaya uygun genel amaçlı bir API'ye hem de belgelerin metnini tanımak için optimize edilmiş bir API'ye sahiptir. Genel amaçlı API'nin hem cihaz içi hem de bulut tabanlı modelleri vardır. Belge metni tanıma yalnızca bulut tabanlı bir model olarak mevcuttur. Bulut ve cihaz üstü modellerin karşılaştırması için genel bakışa bakın.
Sen başlamadan önce
- Henüz uygulamanıza Firebase'i eklemediyseniz, başlangıç kılavuzundaki adımları izleyerek bunu yapın.
- ML Kit kitaplıklarını Pod dosyanıza ekleyin:
pod 'Firebase/MLVision', '6.25.0' # If using an on-device API: pod 'Firebase/MLVisionTextModel', '6.25.0'
Projenizin Pod'larını yükledikten veya güncelledikten sonra, Xcode projenizi.xcworkspace
kullanarak açtığınızdan emin olun. - Uygulamanızda Firebase'i içe aktarın:
Süratli
import Firebase
Amaç-C
@import Firebase;
Bulut tabanlı modeli kullanmak istiyorsanız ve projeniz için Bulut tabanlı API'leri henüz etkinleştirmediyseniz, şimdi yapın:
- Firebase konsolunun ML Kit API'leri sayfasını açın.
Projenizi henüz bir Blaze fiyatlandırma planına yükseltmediyseniz, bunu yapmak için Yükselt'e tıklayın. (Yalnızca projeniz Blaze planında değilse yükseltme yapmanız istenir.)
Yalnızca Blaze düzeyindeki projeler Bulut tabanlı API'leri kullanabilir.
- Bulut tabanlı API'ler zaten etkinleştirilmemişse Bulut Tabanlı API'leri Etkinleştir 'i tıklayın.
Yalnızca cihazdaki modeli kullanmak istiyorsanız bu adımı atlayabilirsiniz.
Artık resimlerdeki metni tanımaya başlamaya hazırsınız.
Giriş resmi yönergeleri
ML Kit'in metni doğru bir şekilde tanıması için giriş görüntülerinin yeterli piksel verisi ile temsil edilen metin içermesi gerekir. İdeal olarak, Latince metin için her karakter en az 16x16 piksel olmalıdır. Çince, Japonca ve Korece metinler için (yalnızca bulut tabanlı API'ler tarafından desteklenir), her karakter 24x24 piksel olmalıdır. Tüm diller için, karakterlerin 24x24 pikselden daha büyük olması için genellikle doğruluk avantajı yoktur.
Bu nedenle, örneğin, 640x480 boyutundaki bir görüntü, görüntünün tüm genişliğini kaplayan bir kartviziti taramak için iyi sonuç verebilir. Letter boyutunda kağıda yazdırılan bir belgeyi taramak için 720x1280 piksel boyutunda bir görüntü gerekebilir.
Zayıf görüntü odağı, metin tanıma doğruluğuna zarar verebilir. Kabul edilebilir sonuçlar almıyorsanız, kullanıcıdan resmi yeniden çekmesini istemeyi deneyin.
Gerçek zamanlı bir uygulamada metin tanıyorsanız, giriş görüntülerinin genel boyutlarını da göz önünde bulundurmak isteyebilirsiniz. Daha küçük görüntüler daha hızlı işlenebilir, bu nedenle gecikmeyi azaltmak için görüntüleri daha düşük çözünürlüklerde yakalayın (yukarıdaki doğruluk gereksinimlerini göz önünde bulundurarak) ve metnin görüntünün mümkün olduğu kadar çok yer kaplamasını sağlayın. Ayrıca , gerçek zamanlı performansı iyileştirmeye yönelik ipuçlarına bakın.
Resimlerdeki metni tanıma
Cihazdaki veya bulut tabanlı bir model kullanarak bir görüntüdeki metni tanımak için, aşağıda açıklandığı gibi metin tanıyıcıyı çalıştırın.
1. Metin tanıyıcıyı çalıştırın
Görüntüyü "UIImage" veya "CMSampleBufferRef" olarak "VisionTextRecognizer"ın "process(_:completion:)" yöntemine iletin:-
onDeviceTextRecognizer
veyacloudTextRecognizer
öğesini çağırarakVisionTextRecognizer
örneğini alın:Süratli
Cihazdaki modeli kullanmak için:
let vision = Vision.vision() let textRecognizer = vision.onDeviceTextRecognizer()
Bulut modelini kullanmak için:
let vision = Vision.vision() let textRecognizer = vision.cloudTextRecognizer() // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages let options = VisionCloudTextRecognizerOptions() options.languageHints = ["en", "hi"] let textRecognizer = vision.cloudTextRecognizer(options: options)
Amaç-C
Cihazdaki modeli kullanmak için:
FIRVision *vision = [FIRVision vision]; FIRVisionTextRecognizer *textRecognizer = [vision onDeviceTextRecognizer];
Bulut modelini kullanmak için:
FIRVision *vision = [FIRVision vision]; FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizer]; // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages FIRVisionCloudTextRecognizerOptions *options = [[FIRVisionCloudTextRecognizerOptions alloc] init]; options.languageHints = @[@"en", @"hi"]; FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizerWithOptions:options];
Bir
UIImage
veya birCMSampleBufferRef
kullanarak birVisionImage
nesnesi oluşturun.Bir
UIImage
kullanmak için:- Gerekirse görüntüyü,
imageOrientation
özelliği.up
olacak şekilde döndürün. - Doğru döndürülmüş
UIImage
kullanarak birVisionImage
nesnesi oluşturun. Herhangi bir döndürme meta verisi belirtmeyin; varsayılan değer olan.topLeft
kullanılmalıdır.Süratli
let image = VisionImage(image: uiImage)
Amaç-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Bir
CMSampleBufferRef
kullanmak için:CMSampleBufferRef
arabelleğinde bulunan görüntü verilerinin yönünü belirten birVisionImageMetadata
nesnesi oluşturun.Görüntü yönünü almak için:
Süratli
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Amaç-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
Ardından, meta veri nesnesini oluşturun:
Süratli
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Amaç-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
-
CMSampleBufferRef
nesnesini ve döndürme meta verilerini kullanarak birVisionImage
nesnesi oluşturun:Süratli
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Amaç-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Gerekirse görüntüyü,
- Ardından, görüntüyü
process(_:completion:)
yöntemine iletin:Süratli
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // ... return } // Recognized text }
Amaç-C
[textRecognizer processImage:image completion:^(FIRVisionText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // ... return; } // Recognized text }];
2. Tanınan metin bloklarından metin ayıklayın
Metin tanıma işlemi başarılı olursa, bir [`VisionText`][VisionText] nesnesi döndürür. Bir 'VisionText' nesnesi, görüntüde tanınan tam metni ve sıfır veya daha fazla ['VisionTextBlock'][VisionTextBlock] nesnesini içerir. Her 'VisionTextBlock', sıfır veya daha fazla ['VisionTextLine'][VisionTextLine] nesnesi içeren dikdörtgen bir metin bloğunu temsil eder. Her 'VisionTextLine' nesnesi, sözcükleri ve sözcük benzeri varlıkları (tarihler, sayılar vb.) temsil eden sıfır veya daha fazla ['VisionTextElement'][VisionTextElement] nesnesi içerir. Her 'VisionTextBlock', 'VisionTextLine' ve 'VisionTextElement' nesnesi için, bölgede tanınan metni ve bölgenin sınırlayıcı koordinatlarını alabilirsiniz. Örneğin:Süratli
let resultText = result.text for block in result.blocks { let blockText = block.text let blockConfidence = block.confidence let blockLanguages = block.recognizedLanguages let blockCornerPoints = block.cornerPoints let blockFrame = block.frame for line in block.lines { let lineText = line.text let lineConfidence = line.confidence let lineLanguages = line.recognizedLanguages let lineCornerPoints = line.cornerPoints let lineFrame = line.frame for element in line.elements { let elementText = element.text let elementConfidence = element.confidence let elementLanguages = element.recognizedLanguages let elementCornerPoints = element.cornerPoints let elementFrame = element.frame } } }
Amaç-C
NSString *resultText = result.text; for (FIRVisionTextBlock *block in result.blocks) { NSString *blockText = block.text; NSNumber *blockConfidence = block.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages; NSArray<NSValue *> *blockCornerPoints = block.cornerPoints; CGRect blockFrame = block.frame; for (FIRVisionTextLine *line in block.lines) { NSString *lineText = line.text; NSNumber *lineConfidence = line.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages; NSArray<NSValue *> *lineCornerPoints = line.cornerPoints; CGRect lineFrame = line.frame; for (FIRVisionTextElement *element in line.elements) { NSString *elementText = element.text; NSNumber *elementConfidence = element.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *elementLanguages = element.recognizedLanguages; NSArray<NSValue *> *elementCornerPoints = element.cornerPoints; CGRect elementFrame = element.frame; } } }
Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları
Gerçek zamanlı bir uygulamada metni tanımak için cihazdaki modeli kullanmak istiyorsanız, en iyi kare hızlarını elde etmek için şu yönergeleri izleyin:
- Metin tanıyıcıya gaz kelebeği çağrıları. Metin tanıyıcı çalışırken yeni bir video karesi kullanıma sunulursa, kareyi bırakın.
- Giriş görüntüsünün üzerine grafik bindirmek için metin tanıyıcının çıkışını kullanıyorsanız, önce ML Kit'ten sonucu alın, ardından görüntüyü ve bindirmeyi tek bir adımda oluşturun. Bunu yaparak, her bir giriş karesi için yalnızca bir kez görüntüleme yüzeyini oluşturursunuz. Bir örnek için vitrin örnek uygulamasında önizlemeOverlayView ve FIRDetectionOverlayView sınıflarına bakın.
- Görüntüleri daha düşük çözünürlükte çekmeyi düşünün. Ancak, bu API'nin resim boyutu gereksinimlerini de unutmayın.
Sonraki adımlar
- Cloud API kullanan bir uygulamayı üretime dağıtmadan önce , yetkisiz API erişiminin etkisini önlemek ve azaltmak için bazı ek adımlar atmalısınız.
Belge görüntülerindeki metni tanıma
Bir belgenin metnini tanımak için, bulut tabanlı belge metin tanıyıcısını aşağıda açıklandığı gibi yapılandırın ve çalıştırın.
Aşağıda açıklanan belge metni tanıma API'si, belge görüntüleriyle çalışmak için daha uygun olması amaçlanan bir arabirim sağlar. Ancak, seyrek metin API'si tarafından sağlanan arayüzü tercih ederseniz, bulut metin tanıyıcıyı yoğun metin modelini kullanacak şekilde yapılandırarak belgeleri taramak için kullanabilirsiniz.
Belge metni tanıma API'sini kullanmak için:
1. Metin tanıyıcıyı çalıştırın
GörüntüyüUIImage
veya CMSampleBufferRef
olarak VisionDocumentTextRecognizer
process(_:completion:)
yöntemine iletin:-
VisionDocumentTextRecognizer
çağırarakcloudDocumentTextRecognizer
örneğini alın:Süratli
let vision = Vision.vision() let textRecognizer = vision.cloudDocumentTextRecognizer() // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages let options = VisionCloudDocumentTextRecognizerOptions() options.languageHints = ["en", "hi"] let textRecognizer = vision.cloudDocumentTextRecognizer(options: options)
Amaç-C
FIRVision *vision = [FIRVision vision]; FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizer]; // Or, to provide language hints to assist with language detection: // See https://cloud.google.com/vision/docs/languages for supported languages FIRVisionCloudDocumentTextRecognizerOptions *options = [[FIRVisionCloudDocumentTextRecognizerOptions alloc] init]; options.languageHints = @[@"en", @"hi"]; FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizerWithOptions:options];
Bir
UIImage
veya birCMSampleBufferRef
kullanarak birVisionImage
nesnesi oluşturun.Bir
UIImage
kullanmak için:- Gerekirse görüntüyü,
imageOrientation
özelliği.up
olacak şekilde döndürün. - Doğru döndürülmüş
UIImage
kullanarak birVisionImage
nesnesi oluşturun. Herhangi bir döndürme meta verisi belirtmeyin; varsayılan değer olan.topLeft
kullanılmalıdır.Süratli
let image = VisionImage(image: uiImage)
Amaç-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Bir
CMSampleBufferRef
kullanmak için:CMSampleBufferRef
arabelleğinde bulunan görüntü verilerinin yönünü belirten birVisionImageMetadata
nesnesi oluşturun.Görüntü yönünü almak için:
Süratli
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Amaç-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
Ardından, meta veri nesnesini oluşturun:
Süratli
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Amaç-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
-
CMSampleBufferRef
nesnesini ve döndürme meta verilerini kullanarak birVisionImage
nesnesi oluşturun:Süratli
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Amaç-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Gerekirse görüntüyü,
- Ardından, görüntüyü
process(_:completion:)
yöntemine iletin:Süratli
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // ... return } // Recognized text }
Amaç-C
[textRecognizer processImage:image completion:^(FIRVisionDocumentText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // ... return; } // Recognized text }];
2. Tanınan metin bloklarından metin ayıklayın
Metin tanıma işlemi başarılı olursa, birVisionDocumentText
nesnesi döndürür. Bir VisionDocumentText
nesnesi, görüntüde tanınan tam metni ve tanınan belgenin yapısını yansıtan nesneler hiyerarşisini içerir: Her VisionDocumentTextBlock
, VisionDocumentTextParagraph
, VisionDocumentTextWord
ve VisionDocumentTextSymbol
nesnesi için bölgede tanınan metni ve bölgenin sınırlayıcı koordinatlarını alabilirsiniz.
Örneğin:
Süratli
let resultText = result.text for block in result.blocks { let blockText = block.text let blockConfidence = block.confidence let blockRecognizedLanguages = block.recognizedLanguages let blockBreak = block.recognizedBreak let blockCornerPoints = block.cornerPoints let blockFrame = block.frame for paragraph in block.paragraphs { let paragraphText = paragraph.text let paragraphConfidence = paragraph.confidence let paragraphRecognizedLanguages = paragraph.recognizedLanguages let paragraphBreak = paragraph.recognizedBreak let paragraphCornerPoints = paragraph.cornerPoints let paragraphFrame = paragraph.frame for word in paragraph.words { let wordText = word.text let wordConfidence = word.confidence let wordRecognizedLanguages = word.recognizedLanguages let wordBreak = word.recognizedBreak let wordCornerPoints = word.cornerPoints let wordFrame = word.frame for symbol in word.symbols { let symbolText = symbol.text let symbolConfidence = symbol.confidence let symbolRecognizedLanguages = symbol.recognizedLanguages let symbolBreak = symbol.recognizedBreak let symbolCornerPoints = symbol.cornerPoints let symbolFrame = symbol.frame } } } }
Amaç-C
NSString *resultText = result.text; for (FIRVisionDocumentTextBlock *block in result.blocks) { NSString *blockText = block.text; NSNumber *blockConfidence = block.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *blockRecognizedLanguages = block.recognizedLanguages; FIRVisionTextRecognizedBreak *blockBreak = block.recognizedBreak; CGRect blockFrame = block.frame; for (FIRVisionDocumentTextParagraph *paragraph in block.paragraphs) { NSString *paragraphText = paragraph.text; NSNumber *paragraphConfidence = paragraph.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *paragraphRecognizedLanguages = paragraph.recognizedLanguages; FIRVisionTextRecognizedBreak *paragraphBreak = paragraph.recognizedBreak; CGRect paragraphFrame = paragraph.frame; for (FIRVisionDocumentTextWord *word in paragraph.words) { NSString *wordText = word.text; NSNumber *wordConfidence = word.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *wordRecognizedLanguages = word.recognizedLanguages; FIRVisionTextRecognizedBreak *wordBreak = word.recognizedBreak; CGRect wordFrame = word.frame; for (FIRVisionDocumentTextSymbol *symbol in word.symbols) { NSString *symbolText = symbol.text; NSNumber *symbolConfidence = symbol.confidence; NSArray<FIRVisionTextRecognizedLanguage *> *symbolRecognizedLanguages = symbol.recognizedLanguages; FIRVisionTextRecognizedBreak *symbolBreak = symbol.recognizedBreak; CGRect symbolFrame = symbol.frame; } } } }
Sonraki adımlar
- Cloud API kullanan bir uygulamayı üretime dağıtmadan önce , yetkisiz API erişiminin etkisini önlemek ve azaltmak için bazı ek adımlar atmalısınız.