일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 탐색
- Greedy
- BFS
- 캡스톤정리
- 문제풀이
- 플로이드와샬
- Node.js
- Blockchain
- 그리디
- Docker
- 실버쥐
- NeuralNetwork
- mysql
- 알고리즘
- Algorithm
- 백준
- Swift
- 백트래킹
- dp
- Stack
- DeepLearning
- 풀이
- 부르트포스
- C++
- ios
- sigmoid
- ReLU
- dfs
- 프로그래머스
- 그래프
- Today
- Total
개발아 담하자
[iOS] MLKit 를 사용한 사진 속 텍스트 인식하기 본문
최근 티켓 사진 속 텍스트를 인식해야하는 사이드 프로젝트를 시작했습니다.
텍스트 인식 방법으로 구글에서 제공하는 MLKit를 사용하기로 했습니다.
인식해야 하는 뮤지컬 티켓의 사진 입니다.
공식 문서를 참고해 작성했습니다.
https://developers.google.com/ml-kit/vision/text-recognition
라이브러리 설치
영어가 아닌 한글을 인식해야 하므로 한글 인식이 지원되는 베타 버전을 사용했습니다.
(베타 버전은 한글 외에도 라틴어, 중국어, 일본어 등을 지원합니다.)
pod 'GoogleMLKit/TextRecognitionKorean', '2.3.0'
Podfile 에 입력한 후 install 합니다.
TextRecognizer 생성
import MLKitTextRecognitionKorean
let koreanOptions = KoreanTextRecognizerOptions()
let koreanTextRecognizer = TextRecognizer.textRecognizer(options: koreanOptions)
이미지 준비
먼저 텍스트 인식을 원하는 이미지를 미리 에셋 파일에 넣어둡니다.
import MLKitVision
let image = VisionImage(image: UIImage(named: "ticket")!)
image.orientation = imageOrientation(deviceOrientation: UIDevice.current.orientation, cameraPosition: .back) // 아직 작성 안 했음!
VisionImage 에 에셋에 넣어 둔 UIImage 파일을 넣습니다. (공식 문서를 살펴보니 UIImage 말고 CMSampleBuffer 를 사용해도 된다고 하니 참고해주세용)
이제 VisionImage 의 oreintation 을 설정할 imgaeOrientation 함수를 작성해야 합니다.
import AVFoundation
func imageOrientation(
deviceOrientation: UIDeviceOrientation,
cameraPosition: AVCaptureDevice.Position
) -> UIImage.Orientation {
switch deviceOrientation {
case .portrait:
return cameraPosition == .front ? .leftMirrored : .right
case .landscapeLeft:
return cameraPosition == .front ? .downMirrored : .up
case .portraitUpsideDown:
return cameraPosition == .front ? .rightMirrored : .left
case .landscapeRight:
return cameraPosition == .front ? .upMirrored : .down
case .faceDown, .faceUp, .unknown:
return .up
}
}
imageOrientation 은 UIDeviceOreintation 과 AVCaptureDevice.Position 을 매개변수로 받고 있습니다.
koreanTextRecognizer.process(image) { result, error in
guard error == nil, let result = result else {
// Error handling
print("error")
return
}
let resultText = result.text
print("resultText: \(resultText)")
}
이제 이미지를 처리합니다!
INFO: Initialized TensorFlow Lite runtime.
resultText: <핑크퐁과 상어가족의 겨을나라> 초대현장교환권
롯데마트
R석 (1인1매)
소: KT&G 상상마당 대치아트홀
장
관람일자: 2017-12-28[목] 14:00
관람연령: 20개월 이상 관람가능
롯데마트
R석 (1인1 매D
어린이 뮤지컬 <핑크퐁과
상어가족의 겨울나라>
본 교환권은 공연당일 매표소 교환권 창구에서 좌석권으로 교환가능합니다.
공연 당일 공연시간 1시간전에서 30분전까지 교환권을 제출하셔야만 교환가능 합니다.
본 교환권 현장교환시 좌석 지정이 불가하며, 차액지불을 통한 좌석등급 변경이 불가 합니다.
2017-12-28[목] 14:00
T&G 상상마당 대치아트홀
교환권 분실이나 미소지시 교환이 불가능(관람불가)하며 재 발행되자 않습니다.
*문의전화: 클립서비스 1577-3363 *판매/때매 불가
코드를 실행시키면 위와 같은 내용이 출력됩니다. 아주 완벽한 인식은 아니지만 생각보다 정확도가 높습니다.
텍스트 추출하기
TextRecognizer 는 Block, Line, Element 단위로 추출이 가능합니다. (사진 참조)
잘 사용한다면 특정 텍스트를 추출하기에 용이할 것 같습니다.
for block in result.blocks {
let blockText = block.text
print("block: \(blockText)")
for line in block.lines {
let lineText = line.text
print("line: \(lineText)")
for element in line.elements {
let elementText = element.text
print("element: \(elementText)")
}
}
}
result 블락에 위와 같이 block, line, elemet 단위로 추출하고 출력해봤습니다.
block: <핑크퐁과 상어가족의 겨을나라> 초대현장교환권
line: <핑크퐁과 상어가족의 겨을나라> 초대현장교환권
element: <핑크퐁과
element: 상어가족의
element: 겨을나라>
element: 초대현장교환권
block: 롯데마트
line: 롯데마트
element: 롯데마트
block: R석 (1인1매)
line: R석 (1인1매)
element: R석
element: (1인1매)
block: 소: KT&G 상상마당 대치아트홀
line: 소: KT&G 상상마당 대치아트홀
element: 소:
element: KT&G
element: 상상마당
element: 대치아트홀
block: 장
line: 장
element: 장
block: 관람일자: 2017-12-28[목] 14:00
line: 관람일자: 2017-12-28[목] 14:00
element: 관람일자:
element: 2017-12-28[목]
element: 14:00
block: 관람연령: 20개월 이상 관람가능
line: 관람연령: 20개월 이상 관람가능
element: 관람연령:
element: 20개월
element: 이상
element: 관람가능
block: 롯데마트
line: 롯데마트
element: 롯데마트
block: R석 (1인1 매D
line: R석 (1인1 매D
element: R석
element: (1인1
element: 매D
block: 어린이 뮤지컬 <핑크퐁과
상어가족의 겨울나라>
line: 어린이 뮤지컬 <핑크퐁과
element: 어린이
element: 뮤지컬
element: <핑크퐁과
line: 상어가족의 겨울나라>
element: 상어가족의
element: 겨울나라>
block: 본 교환권은 공연당일 매표소 교환권 창구에서 좌석권으로 교환가능합니다.
line: 본 교환권은 공연당일 매표소 교환권 창구에서 좌석권으로 교환가능합니다.
element: 본
element: 교환권은
element: 공연당일
element: 매표소
element: 교환권
element: 창구에서
element: 좌석권으로
element: 교환가능합니다.
block: 공연 당일 공연시간 1시간전에서 30분전까지 교환권을 제출하셔야만 교환가능 합니다.
line: 공연 당일 공연시간 1시간전에서 30분전까지 교환권을 제출하셔야만 교환가능 합니다.
element: 공연
element: 당일
element: 공연시간
element: 1시간전에서
element: 30분전까지
element: 교환권을
element: 제출하셔야만
element: 교환가능
element: 합니다.
block: 본 교환권 현장교환시 좌석 지정이 불가하며, 차액지불을 통한 좌석등급 변경이 불가 합니다.
line: 본 교환권 현장교환시 좌석 지정이 불가하며, 차액지불을 통한 좌석등급 변경이 불가 합니다.
element: 본
element: 교환권
element: 현장교환시
element: 좌석
element: 지정이
element: 불가하며,
element: 차액지불을
element: 통한
element: 좌석등급
element: 변경이
element: 불가
element: 합니다.
block: 2017-12-28[목] 14:00
T&G 상상마당 대치아트홀
line: 2017-12-28[목] 14:00
element: 2017-12-28[목]
element: 14:00
line: T&G 상상마당 대치아트홀
element: T&G
element: 상상마당
element: 대치아트홀
block: 교환권 분실이나 미소지시 교환이 불가능(관람불가)하며 재 발행되자 않습니다.
line: 교환권 분실이나 미소지시 교환이 불가능(관람불가)하며 재 발행되자 않습니다.
element: 교환권
element: 분실이나
element: 미소지시
element: 교환이
element: 불가능(관람불가)하며
element: 재
element: 발행되자
element: 않습니다.
block: *문의전화: 클립서비스 1577-3363 *판매/때매 불가
line: *문의전화: 클립서비스 1577-3363 *판매/때매 불가
element: *문의전화:
element: 클립서비스
element: 1577-3363
element: *판매/때매
element: 불가
완벽하지는..않지만..!!! 만족스럽습니당
'📱 iOS' 카테고리의 다른 글
[iOS] Tuist 를 활용한 프로젝트 모듈화 (1) (1) | 2022.08.19 |
---|---|
[iOS] Memory Leak (1) : 강한 순환 참조 (4) | 2021.11.27 |
[iOS] IDFA 적용하기 (0) | 2021.10.29 |
[iOS] Fridump3 를 사용한 메모리 덤프 (0) | 2021.10.01 |
[iOS/Swift] storyboard 없이 UI 그리기 (iOS 13 버전 이하) (0) | 2021.09.12 |