זיהוי טקסט בתמונות באמצעות Firebase ML ב-iOS

אפשר להשתמש ב-Firebase ML כדי לזהות טקסט בתמונות. ל-Firebase ML יש ממשק API למטרות כלליות שמתאים לזיהוי טקסט בתמונות, כמו הטקסט של שלט רחוב, וגם ממשק API מותאם לזיהוי טקסט במסמכים.

לפני שמתחילים

    אם עדיין לא הוספתם את Firebase לאפליקציה, צריך לבצע את הפעולות הבאות במדריך לתחילת העבודה.

    שימוש ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.

    1. ב-Xcode, כשפרויקט האפליקציה פתוח, עוברים אל File > (קובץ >) הוספת חבילות.
    2. כשמופיעה בקשה, מוסיפים את המאגר של Firebase SDK לפלטפורמות של Apple:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. בוחרים את הספרייה Firebase ML.
    5. מוסיפים את הדגל -ObjC לקטע סימונים של מקשר אחר בהגדרות ה-build של היעד.
    6. בסיום, Xcode יתחיל לפתור את הבעיה ותוריד את של יחסי התלות ברקע.

    עכשיו מבצעים הגדרה בתוך האפליקציה:

    1. מייבאים את Firebase לאפליקציה:

      Swift

      import FirebaseMLModelDownloader

      Objective-C

      @import FirebaseMLModelDownloader;
  1. אם עדיין לא הפעלתם ממשקי API מבוססי-ענן בפרויקט שלכם, אתם צריכים לעשות זאת עכשיו:

    1. פותחים את Firebase ML דף ממשקי ה-API במסוף Firebase.
    2. אם עדיין לא שדרגתם את הפרויקט לתוכנית התמחור והתשלומים של Blaze, לוחצים על כדי לעשות זאת, אפשר לשדרג. (תתבקש לשדרג רק אם הוא לא בתוכנית Blaze.)

      רק בפרויקטים ברמת Blaze אפשר להשתמש בממשקי API מבוססי-ענן.

    3. אם ממשקי API מבוססי-ענן עדיין לא מופעלים, לוחצים על הפעלת ממשקי API מבוססי-ענן. ממשקי API.

עכשיו אתם מוכנים להתחיל לזהות טקסט בתמונות.

הנחיות להוספת תמונה

  • כדי ש-Firebase ML יוכל לזהות טקסט באופן מדויק, תמונות הקלט צריכות לכלול שמיוצג על ידי כמות מספקת של נתוני פיקסלים. באופן אידיאלי, לטקסט לטינית, כל תו צריך להיות בגודל של 16x16 פיקסלים לפחות. בסינית, טקסט ביפנית ובקוריאנית, כל אחד צריך להיות בגודל 24x24 פיקסלים. בדרך כלל, לא משנה מה השפה, אין יתרון של דיוק כשהתווים גדולים מ-24x24 פיקסלים.

    כך, לדוגמה, תמונה בגודל 640x480 יכולה להתאים לסריקת כרטיס ביקור שתופס את כל הרוחב של התמונה. כדי לסרוק מסמך שהודפס על על נייר בגודל אות, ייתכן שיהיה צורך בתמונה בגודל 720x1280 פיקסלים.

  • מיקוד לא טוב של תמונה עלול לפגוע בדיוק זיהוי הטקסט. אם אתם לא כדי לקבל תוצאות מקובלות, נסו לבקש מהמשתמש לצלם מחדש את התמונה.


זיהוי טקסט בתמונות

כדי לזהות טקסט בתמונה, מריצים את הכלי לזיהוי טקסט כפי שמתואר בהמשך.

1. הרצה של מזהה הטקסט

מעבירים את התמונה כ-UIImage או כ-CMSampleBufferRef לשיטה process(_:completion:) של VisionTextRecognizer:

  1. כדי לקבל מופע של 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];
  2. כדי לקרוא ל-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];
  3. לאחר מכן, מעבירים את התמונה ל-method 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;
    }
  }
}

השלבים הבאים


זיהוי טקסט בתמונות של מסמכים

כדי לזהות טקסט של מסמך, יש להגדיר ולהריץ את מזהה טקסט של מסמכים, כמו שמתואר בהמשך.

ממשק ה-API לזיהוי טקסט במסמכים, המתואר בהמשך, מספק ממשק אמור להיות נוח יותר לעבודה עם תמונות של מסמכים. אבל, לפעמים אם אתם מעדיפים את הממשק שמסופק על ידי ה-sparse text API, תוכלו להשתמש בו במקום לסרוק מסמכים על ידי הגדרת מזהה הטקסט בענן להשתמש במודל הטקסט הדחיסה.

כדי להשתמש ב-Document Text Recognition API:

1. הרצה של מזהה הטקסט

מעבירים את התמונה כ-UIImage או כ-CMSampleBufferRef אל process(_:completion:) של VisionDocumentTextRecognizer method:

  1. כדי לקבל מופע של 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];
  2. כדי לקרוא ל-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];
  3. לאחר מכן, מעבירים את התמונה ל-method 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;
      }
    }
  }
}

השלבים הבאים