Skip to content

Instantly share code, notes, and snippets.

@davidseek
Last active January 18, 2021 22:54
Show Gist options
  • Save davidseek/965f1b4195104f2f7fabb9717f498df3 to your computer and use it in GitHub Desktop.
Save davidseek/965f1b4195104f2f7fabb9717f498df3 to your computer and use it in GitHub Desktop.
TextRecognizer.swift
import Foundation
import Vision
struct TextRecognizer {
static func get(from image: CGImage, onComplete: @escaping (String) -> Void) {
// We kick off a text recognition handler
handle(VNRecognizeTextRequest { (request, error) in
// First we need to make sure, that the request returned results
guard let observations = request.results as? [VNRecognizedTextObservation] else {
// MARK: - TODO, handle appropriately
return
}
// We're going to iterate over all possible results
observations.forEach { observation in
// And for each result, we're only going to care for the top result
// Since our recognizer has to return at max one letter,
// this should be a fairly acceptable way of handling that.
observation.topCandidates(1).forEach { text in
// Lastly we're passing the String to our closure
onComplete(text.string)
}
}
}, for: image)
}
// MARK: - Private
// We have extracted the handler into its own class to clean up the code.
// Without it we've had a whole bunch of nesting.
private static func handle(_ request: VNRecognizeTextRequest, for image: CGImage) {
// Since we only need one letter, we can go with the highest accuracy
request.recognitionLevel = .accurate
// The language is en_GB
request.recognitionLanguages = ["en_GB"]
// I found, that the letter Q wasn't always recognized well.
// Adding it to custom words solved the issue for good.
request.customWords = ["Q"]
do {
try VNImageRequestHandler(cgImage: image, options: [:]).perform([request])
} catch {
fatalError(error.localizedDescription)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment