Resimlerdeki metni tanımak için ML Kit'i kullanabilirsiniz. ML Kit, hem sokak tabelası metni gibi resimlerdeki metni tanımaya uygun genel amaçlı bir API'ye hem de belge 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
- Firebase'i uygulamanıza henüz 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 hemen 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 istenecektir.)
Yalnızca Blaze düzeyindeki projeler Bulut tabanlı API'leri kullanabilir.
- Bulut tabanlı API'ler henüz etkin değilse 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 hazırsınız.
Giriş görseli yönergeleri
ML Kit'in metni doğru şekilde tanıyabilmesi için giriş görüntülerinin yeterli piksel verileriyle temsil edilen metin içermesi gerekir. İdeal olarak Latince metinlerde 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 büyük olmasının genellikle doğruluk açısından bir avantajı yoktur.
Örneğin, 640x480 boyutunda 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 basılmış 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 alamıyorsanız kullanıcıdan görüntüyü yeniden yakalamasını istemeyi deneyin.
Gerçek zamanlı bir uygulamada metni tanıyorsanız, giriş görüntülerinin genel boyutlarını da dikkate almak isteyebilirsiniz. Daha küçük resimler daha hızlı işlenebilir; bu nedenle gecikmeyi azaltmak için, resimleri daha düşük çözünürlükte çekin (yukarıdaki doğruluk gerekliliklerini göz önünde bulundurarak) ve metnin resimde mümkün olduğunca fazla yer kaplamasını sağlayın. Ayrıca bkz . Gerçek zamanlı performansı artırmaya yönelik ipuçları .
Resimlerdeki metni tanıma
Cihaz içi veya bulut tabanlı bir model kullanarak görüntüdeki metni tanımak için metin tanıyıcıyı aşağıda açıklandığı şekilde ç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 aktarın:-
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];
UIImage
veyaCMSampleBufferRef
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 şekilde 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];
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ü elde etmek 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 metni çıkarın
Metin tanıma işlemi başarılı olursa, bir [`VisionText`][VisionText] nesnesi döndürülü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 bir `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 bir '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ı artırmaya yönelik ipuçları
Gerçek zamanlı bir uygulamada metni tanımak için cihaz üstü modeli kullanmak istiyorsanız en iyi kare hızlarına ulaşmak için şu yönergeleri izleyin:
- Metin tanıyıcıya yapılan aramaları kısın. Metin tanıyıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse kareyi bırakın.
- Grafikleri giriş görüntüsüne yerleştirmek için metin tanıyıcının çıktısını kullanıyorsanız, önce ML Kit'ten sonucu alın, ardından tek adımda görüntüyü oluşturun ve kaplayın. Bunu yaparak, her giriş karesi için ekran yüzeyini yalnızca bir kez görüntüleyebilirsiniz. Örnek için vitrin örnek uygulamasındaki ö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şimini önlemek ve etkisini azaltmak için bazı ek adımlar atmanız gerekir.
Belge görsellerindeki metni tanıma
Bir belgenin metnini tanımak için bulut tabanlı belge metin tanıyıcıyı aşağıda açıklandığı şekilde yapılandırın ve çalıştırın.
Aşağıda açıklanan belge metni tanıma API'si, belge görselleriyle çalışmak için daha kullanışlı olması amaçlanan bir arayüz 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 bunu kullanabilirsiniz.
Belge metni tanıma API'sini kullanmak için:
1. Metin tanıyıcıyı çalıştırın
Görüntüyü birUIImage
veya CMSampleBufferRef
olarak VisionDocumentTextRecognizer
process(_:completion:)
yöntemine iletin:-
cloudDocumentTextRecognizer
öğesini çağırarakVisionDocumentTextRecognizer
ö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];
UIImage
veyaCMSampleBufferRef
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 şekilde 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];
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ü elde etmek 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 metni çıkarın
Metin tanıma işlemi başarılı olursaVisionDocumentText
nesnesini döndürür. VisionDocumentText
nesnesi, görüntüde tanınan tam metni ve tanınan belgenin yapısını yansıtan nesnelerin 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şimini önlemek ve etkisini azaltmak için bazı ek adımlar atmanız gerekir.