Pemindaian dokumen dan pengenalan teks dengan VisionKit dan Kerangka Visi di iOS

Hari ini kami akan memindai dokumen dan menampilkan teks yang dikenali dari dokumen ini. Anda tidak perlu menginstal pustaka tambahan untuk ini: VisionKit berguna untuk pemindaian dan Visi untuk pengenalan teks.



Pertama, pastikan Anda menginstal Xcode 11 dan iOS 13 , kemudian buat proyek baru dengan dukungan Storyboard .

Kami akan memindai menggunakan kamera video. Jadi kita perlu menambahkan NSCameraUsageDescription ke Info.plist , tanpa aplikasi ini akan macet.



Memindai


Untuk memindai dokumen, kami menggunakan Kerangka VisionKit . Untuk membuka layar untuk pemindaian, Anda perlu membuat sampel baru dari VNDocumentCameraViewController dan output:

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

Tambahkan VNDocumentCameraViewControllerDelegate ke ViewController :

class ViewController: UIViewController, VNDocumentCameraViewControllerDelegate {
...

Setelah mengklik "Batalkan" atau kesalahan, tutup layar terbuka:

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

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

Setelah memindai dan mengklik "Simpan", yang berikut ini akan berfungsi:

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)
}

Setiap halaman dapat diproses secara individual.

Pengenalan teks


Kami menemukan pemindaian, sekarang kami mengekstrak teks.

Agar semuanya berjalan lancar, kami akan melakukan pengenalan di latar belakang. Untuk melakukan ini, buat DispatchQueue :

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

Untuk pengakuan, kita membutuhkan VNImageRequestHandler dengan gambar dan VNRecognizeTextRequest dengan opsi pengakuanLevel , customWords , recognitionLanguages , serta penangan penyelesaian yang akan memberikan hasil dalam bentuk teks. Setelah selesai, kami mengumpulkan opsi dan tampilan teks terbaik:

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)
        }
    }
}

ViewController terbaru


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)
    }
    
}




Apa berikutnya?


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

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

GitHub project:
github.com/usenbekov / Visi-demo

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


All Articles