[iOS/Swift] VisionKit OCR Api 예제 한글
Swift 언어를 사용하여
Apple Developer에서 제공하는
VisionKit Framework를 사용하여 OCR 개발
서론
VisionKit은 Apple에서 개발한 OCR Api로
VisionKit은 이미지와 iOS 카메라의 Live Video 와 Text 및 구조화된 데이터를 감지하는 기능을 제공한다
심지어 무료! 💸 게다가 성능도 좋아 ~
(대신 한국어 인식률은 떨어짐)
iOS OCR 개발을 한다면 가장 추천한다
🚫 주의 🚫
iOS 13 이상 버전에서만 사용 가능하다
👇 다른 OCR 예제가 궁금하다면? 아래 포스팅들 클릭! 👇
🍀 네이버 OCR 🍀
2023.02.01 - [iOS Swift/iOS Swift 예제] - [iOS/Swift] Google MLKit Vision OCR Api 예제
🏀 구글 OCR 🏀
2023.02.01 - [iOS Swift/iOS Swift - 예제] - [iOS/Swift] Google MLKit Vision OCR Api 예제
Chap1. Vision 라이브러리를 Import
VisionKit을 사용하기 위해서 라이브러리는 Import 만 하면 된다!
매우 간단
import VisionKit
import Vision
Chap2. CGImage로 이미지 타입 변환
이미지 인식을 요청하는 Handler를 생성할 때
= VNImageRequestHandler( cgImage: , options: [:])
cgImage를 요구한다! 원하는 UIImgae를 cgImage로 변환한다
let image = UIImage(named: "demo")
guard let cgImage = image?.cgImage else {
fatalError("could not get image")
}
Chap3. VNRecognizeTextRequest 인스턴스 만들기
이제부터 본격적으로 VisionKit을 사용해 보자!
VisionKit을 사용하기 위해서는 가장 먼저 인스턴스 생성부터 해야 한다!
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
let request = VNRecognizeTextRequest{ [weak self]request, error in
guard let observations = request.results as? [VNRecognizedTextObservation],
error == nil else{
return
}
// 한 줄이 끝나는 부분마다 \n
let text = observations.compactMap({
$0.topCandidates(1).first?.string
}).joined(separator: "\n")
// ui 변경은 main thread에서만 가능
DispatchQueue.main.async {
self?.label.text = text
print(text)
}
}
Chap4. Vision 버전과 언어 설정
VNRecognizeTextRequest는 다양한 옵션을 가진다
인스턴스를 생성했으면 옵션 설정을 해주자!
나는 버전, 정확도, 번역할 언어 3가지 설정하였다
revision
➡️ VNRecognizeTextRequest의 버전 선택 (현재 revision3 가장 최신)
recognitionLevel
➡️ 비전 인식의 정확도 레벨 선택
recognitionLanguages
➡️ 번역할 언어 선택
if #available(iOS 16.0, *) {
let revision3 = VNRecognizeTextRequestRevision3
request.revision = revision3
request.recognitionLevel = .accurate
request.recognitionLanguages = ["ko-KR"]
request.usesLanguageCorrection = true
do {
var possibleLanguages: Array<String> = []
possibleLanguages = try request.supportedRecognitionLanguages()
print(possibleLanguages)
} catch {
print("Error getting the supported languages.")
}
} else {
// Fallback on earlier versions
request.recognitionLanguages = ["en-US"]
request.usesLanguageCorrection = true
}
VisionKit의 경우 지원하는 언어가 한정적인데,
내가 원하는 언어가 지원하는지 확인할 수 있는 함수가 있다!
supportedRecognitionLanguages()
-> 함수 호출 시 아래와 같이 지원하는 언어가 확인 가능하며,
iOS16 이상, VNRecognizeTextRequestRevision3 버전을 사용하면 아래와 같이 14가지 언어를 지원한다!
* supportedRecognitionLanguages 결과
🌏 지원하는 언어 🌏
영어, 불어, 이탈리아어, 독일어, 스페인어, 포르투갈어(브라질), 중국어 간체, 중국어 번체, 광동어 간체, 광동어 번체, 한글, 일본어, 러시아어, 우크라이나어 |
-> VNRecognizeTextRequestRevision3 기준
Chap5. Request Handler 동작
위에서 설정한 handler, request를 동작한다!
// handler 동작
do{
try handler.perform([request])
} catch {
// 에러 처리
label.text = "\(error)"
print(error)
}
Chap6. 결과 확인하기
한 치의 오차 없는 결과 확인 가능!
Chap7. 전체 소스코드
import Foundation
import VisionKit
import Vision
class VisionViewController: UIViewController{
private let label: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "love")
imageView.contentMode = .scaleAspectFit
return imageView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
view.addSubview(imageView)
recognizeText(image: imageView.image)
print("VisionViewController")
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
imageView.frame = CGRect(
x: 20,
y: view.safeAreaInsets.top,
width: view.frame.size.width-40,
height: view.frame.size.width-40)
label.frame = CGRect(
x: 20,
y: view.frame.size.width + view.safeAreaInsets.top,
width: view.frame.size.width-40,
height: 300)
}
fileprivate func recognizeText(image: UIImage?){
guard let cgImage = image?.cgImage else {
fatalError("could not get image")
}
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
let request = VNRecognizeTextRequest{ [weak self]request, error in
guard let observations = request.results as? [VNRecognizedTextObservation],
error == nil else{
return
}
let text = observations.compactMap({
$0.topCandidates(1).first?.string
}).joined(separator: "\n")
DispatchQueue.main.async {
self?.label.text = text
}
}
if #available(iOS 16.0, *) {
let revision3 = VNRecognizeTextRequestRevision3
request.revision = revision3
request.recognitionLevel = .accurate
request.recognitionLanguages = [commonVisionLang]
request.usesLanguageCorrection = true
do {
var possibleLanguages: Array<String> = []
possibleLanguages = try request.supportedRecognitionLanguages()
print(possibleLanguages)
} catch {
print("Error getting the supported languages.")
}
} else {
// Fallback on earlier versions
request.recognitionLanguages = ["en-US"]
request.usesLanguageCorrection = true
}
do{
try handler.perform([request])
} catch {
label.text = "\(error)"
print(error)
}
}
}