Numérisation de documents et reconnaissance de texte avec VisionKit et Vision Framework sur iOS

Aujourd'hui, nous allons numériser le document et afficher le texte reconnu de ce document. Vous n'avez pas besoin d'installer de bibliothèques supplémentaires pour cela: VisionKit est utile pour la numérisation et Vision pour la reconnaissance de texte.



Tout d'abord, assurez-vous que Xcode 11 et iOS 13 sont installés , puis créez un nouveau projet avec le support Storyboard .

Nous numériserons à l'aide d'une caméra vidéo. Nous devons donc ajouter NSCameraUsageDescription à Info.plist , sans cette application, il plantera.



Balayage


Pour numériser des documents, nous utilisons le cadre VisionKit . Pour ouvrir l'écran de numérisation, vous devez créer un nouvel échantillon à partir de VNDocumentCameraViewController et générer:

let scanner = VNDocumentCameraViewController()
scanner.delegate = self
present(scanner, animated: true)

Ajoutez VNDocumentCameraViewControllerDelegate à ViewController :

class ViewController: UIViewController, VNDocumentCameraViewControllerDelegate {
...

Après avoir cliqué sur «Annuler» ou sur une erreur, fermez l'écran ouvert:

func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
  controller.dismiss(animated: true)
}

func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
  controller.dismiss(animated: true)
}

Après avoir numérisé et cliqué sur «Enregistrer», les éléments suivants fonctionneront:

func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
  for i in 0 ..< scan.pageCount {
    let img = scan.imageOfPage(at: i)
    // recognizeText(inImage: img)
  }
  controller.dismiss(animated: true)
}

Chaque page peut être traitée individuellement.

Reconnaissance de texte


Nous avons compris la numérisation, maintenant nous extrayons le texte.

Pour que tout se passe bien, nous effectuerons une reconnaissance en arrière-plan. Pour ce faire, créez un DispatchQueue :

lazy var workQueue = {
  return DispatchQueue(label: "workQueue", qos: .userInitiated, attributes: [], autoreleaseFrequency: .workItem)
}()

Pour la reconnaissance, nous avons besoin d'un VNImageRequestHandler avec une image et VNRecognizeTextRequest avec les options reconnaissanceLevel , customWords , reconnaissanceLanguages , ainsi que d'un gestionnaire de complétion qui donnera le résultat sous forme de texte. À la fin, nous collectons les meilleures options de texte et affichons:

lazy var textRecognitionRequest: VNRecognizeTextRequest = {
    let req = VNRecognizeTextRequest { (request, error) in
        guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
        
        var resultText = ""
        for observation in observations {
            guard let topCandidate = observation.topCandidates(1).first else { return }
            resultText += topCandidate.string
            resultText += "\n"
        }
        
        DispatchQueue.main.async {
            self.txt.text = resultText
        }
    }
    return req
}()

VNImageRequestHandler :

func recognizeText(inImage: UIImage) {
    guard let cgImage = inImage.cgImage else { return }
    
    workQueue.async {
        let requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
        do {
            try requestHandler.perform([self.textRecognitionRequest])
        } catch {
            print(error)
        }
    }
}

Dernière ViewController


import UIKit
import Vision
import VisionKit

class ViewController: UIViewController, VNDocumentCameraViewControllerDelegate {
    @IBOutlet weak var txt: UITextView!
    
    lazy var workQueue = {
        return DispatchQueue(label: "workQueue", qos: .userInitiated, attributes: [], autoreleaseFrequency: .workItem)
    }()
    
    lazy var textRecognitionRequest: VNRecognizeTextRequest = {
        let req = VNRecognizeTextRequest { (request, error) in
            guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
            
            var resultText = ""
            for observation in observations {
                guard let topCandidate = observation.topCandidates(1).first else { return }
                resultText += topCandidate.string
                resultText += "\n"
            }
            
            DispatchQueue.main.async {
                self.txt.text = self.txt.text + "\n" + resultText
            }
        }
        return req
    }()

    @IBAction func startScan(_ sender: Any) {
        txt.text = ""
        
        let scanner = VNDocumentCameraViewController()
        scanner.delegate = self
        present(scanner, animated: true)
    }
    
    func recognizeText(inImage: UIImage) {
        guard let cgImage = inImage.cgImage else { return }
        
        workQueue.async {
            let requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
            do {
                try requestHandler.perform([self.textRecognitionRequest])
            } catch {
                print(error)
            }
        }
    }
    
    // MARK: - Document Camera VC Delegate
    
    func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
        for i in 0 ..< scan.pageCount {
            let img = scan.imageOfPage(at: i)
            recognizeText(inImage: img)
        }
        
        controller.dismiss(animated: true)
    }
    
    func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
        controller.dismiss(animated: true)
    }
    
    func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
        print(error)
        controller.dismiss(animated: true)
    }
    
}




Et après?


Documentation:
developer.apple.com/documentation/vision
developer.apple.com/documentation/visionkit

WWDC Speech framework video:
developer.apple.com/videos/all-videos/?q=Vision

Projet GitHub:
github.com/usenbekov / vision-demo

Source: https://habr.com/ru/post/undefined/


All Articles