אפשר להשתמש ב-Firebase ML כדי לזהות טקסט בתמונות. Firebase ML כולל גם API לשימוש כללי שמתאים לזיהוי טקסט בתמונות, כמו טקסט של תמרור רחוב, וגם API שעבר אופטימיזציה לזיהוי טקסט במסמכים.
לפני שמתחילים
-
אם עדיין לא הוספתם את Firebase לאפליקציה, אתם צריכים לעשות זאת לפי השלבים שמפורטים במדריך לתחילת העבודה.
- ב-Xcode, כשהפרויקט של האפליקציה פתוח, עוברים אל File > Add Packages (קובץ > הוספת חבילות).
- כשמוצגת בקשה, מוסיפים את מאגר Firebase Apple platforms SDK:
- בוחרים את הספרייה Firebase ML.
- מוסיפים את הדגל
-ObjC
לקטע Other Linker Flags בהגדרות הבנייה של יעד הקישור. - אחרי שתסיימו, פלטפורמת Xcode תתחיל באופן אוטומטי לטפל ביחסי התלות ולהוריד אותם ברקע.
- באפליקציה, מייבאים את Firebase:
Swift
import FirebaseMLModelDownloader
Objective-C
@import FirebaseMLModelDownloader;
-
אם עדיין לא הפעלתם ממשקי API מבוססי-Cloud בפרויקט, עכשיו הזמן לעשות זאת:
- פותחים את Firebase ML הדף APIs במסוף Firebase.
-
אם עדיין לא שדרגתם את הפרויקט לתוכנית התמחור Blaze עם תשלום לפי שימוש, לוחצים על שדרוג כדי לעשות זאת. (תתבקשו לשדרג רק אם הפרויקט שלכם לא נמצא בתוכנית התמחור Blaze).
רק פרויקטים בתוכנית התמחור Blaze יכולים להשתמש בממשקי API מבוססי-Cloud.
- אם ממשקי API מבוססי-ענן לא מופעלים כבר, לוחצים על הפעלת ממשקי API מבוססי-ענן.
משתמשים ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.
https://github.com/firebase/firebase-ios-sdk.git
עכשיו מבצעים הגדרה באפליקציה:
עכשיו אפשר להתחיל לזהות טקסט בתמונות.
הנחיות לגבי תמונות קלט
-
כדי ש-Firebase ML יוכל לזהות טקסט בצורה מדויקת, התמונות שמוזנות צריכות להכיל טקסט שמיוצג על ידי נתוני פיקסלים מספיקים. באופן אידיאלי, עבור טקסט לטיני, כל תו צריך להיות בגודל 16x16 פיקסלים לפחות. בטקסט בסינית, ביפנית או בקוריאנית, כל תו צריך להיות בגודל 24x24 פיקסלים. בכל השפות, בדרך כלל אין יתרון בדיוק אם התווים גדולים מ-24x24 פיקסלים.
לדוגמה, תמונה בגודל 640x480 יכולה להתאים לסריקה של כרטיס ביקור שממלא את כל הרוחב של התמונה. כדי לסרוק מסמך שמודפס על נייר בגודל Letter, יכול להיות שתידרש תמונה בגודל 720x1280 פיקסלים.
-
פוקוס לא טוב של התמונה עלול לפגוע בדיוק של זיהוי הטקסט. אם התוצאות לא מספיק טובות, אפשר לבקש מהמשתמש לצלם מחדש את התמונה.
זיהוי טקסט בתמונות
כדי לזהות טקסט בתמונה, מפעילים את הכלי לזיהוי טקסט כמו שמתואר בהמשך.
1. הפעלת הכלי לזיהוי טקסט
מעבירים את התמונה כ-UIImage
או כ-CMSampleBufferRef
לשיטה process(_:completion:)
של VisionTextRecognizer
:
- מקבלים מופע של
VisionTextRecognizer
על ידי קריאה ל-cloudTextRecognizer
:Swift
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)
Objective-C
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];
-
כדי להתקשר אל Cloud Vision, התמונה צריכה להיות בפורמט של מחרוזת בקידוד Base64. כדי לעבד
UIImage
:Swift
guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return } let base64encodedImage = imageData.base64EncodedString()
Objective-C
NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f); NSString *base64encodedImage = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
-
לאחר מכן, מעבירים את התמונה לשיטה
process(_:completion:)
:Swift
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // ... return } // Recognized text }
Objective-C
[textRecognizer processImage:image completion:^(FIRVisionText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // ... return; } // Recognized text }];
2. חילוץ טקסט מבלוקים של טקסט מזוהה
אם פעולת זיהוי הטקסט תצליח, יוחזר אובייקטVisionText
. אובייקט VisionText
מכיל את הטקסט המלא שזוהה בתמונה, ואפס אובייקטים מסוג VisionTextBlock
או יותר.
כל רכיב VisionTextBlock
מייצג בלוק טקסט מלבני, שמכיל אפס אובייקטים מסוג VisionTextLine
או יותר. כל אובייקט VisionTextLine
מכיל אפס אובייקטים מסוג VisionTextElement
או יותר, שמייצגים מילים וישויות דמויות מילים (תאריכים, מספרים וכו').
לכל אובייקט VisionTextBlock
, VisionTextLine
ו-VisionTextElement
, אפשר לקבל את הטקסט שזוהה באזור ואת קואורדינטות התיחום של האזור.
לדוגמה:
Swift
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 } } }
Objective-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; } } }
השלבים הבאים
- לפני שפורסים לייצור אפליקציה שמשתמשת ב-Cloud API, כדאי לבצע כמה שלבים נוספים כדי למנוע גישה לא מורשית ל-API ולצמצם את ההשפעה שלה.
זיהוי טקסט בתמונות של מסמכים
כדי לזהות את הטקסט במסמך, מגדירים ומריצים את הכלי לזיהוי טקסט במסמך כמו שמתואר בהמשך.
ממשק ה-API לזיהוי טקסט במסמכים, שמתואר בהמשך, נועד להקל על העבודה עם תמונות של מסמכים. אבל אם אתם מעדיפים את הממשק שמספק ה-API של טקסט דליל, אתם יכולים להשתמש בו במקום זאת כדי לסרוק מסמכים. לשם כך, צריך להגדיר את הכלי לזיהוי טקסט בענן לשימוש במודל של טקסט צפוף.
כדי להשתמש ב-API לזיהוי טקסט במסמך:
1. הפעלת הכלי לזיהוי טקסט
מעבירים את התמונה כ-UIImage
או כ-CMSampleBufferRef
לשיטה process(_:completion:)
של VisionDocumentTextRecognizer
:
- מקבלים מופע של
VisionDocumentTextRecognizer
על ידי קריאה ל-cloudDocumentTextRecognizer
:Swift
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)
Objective-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];
-
כדי להתקשר אל Cloud Vision, התמונה צריכה להיות בפורמט של מחרוזת בקידוד Base64. כדי לעבד
UIImage
:Swift
guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return } let base64encodedImage = imageData.base64EncodedString()
Objective-C
NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f); NSString *base64encodedImage = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
-
לאחר מכן, מעבירים את התמונה לשיטה
process(_:completion:)
:Swift
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // ... return } // Recognized text }
Objective-C
[textRecognizer processImage:image completion:^(FIRVisionDocumentText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // ... return; } // Recognized text }];
2. חילוץ טקסט מבלוקים של טקסט מזוהה
אם פעולת זיהוי הטקסט תצליח, יוחזר אובייקטVisionDocumentText
. אובייקט VisionDocumentText
מכיל את הטקסט המלא שזוהה בתמונה ואת ההיררכיה של האובייקטים שמשקפים את המבנה של המסמך שזוהה:
לכל אובייקט VisionDocumentTextBlock
, VisionDocumentTextParagraph
, VisionDocumentTextWord
ו-VisionDocumentTextSymbol
, אפשר לקבל את הטקסט שזוהה באזור ואת קואורדינטות התיחום של האזור.
לדוגמה:
Swift
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 } } } }
Objective-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; } } } }
השלבים הבאים
- לפני שפורסים לייצור אפליקציה שמשתמשת ב-Cloud API, כדאי לבצע כמה שלבים נוספים כדי למנוע גישה לא מורשית ל-API ולצמצם את ההשפעה שלה.