brunch

You can make anything
by writing

C.S.Lewis

by 티맵모빌리티 Jun 14. 2022

Vision API로 카드번호 인식 개발하기(OCR)

12편 – 티맵 내 많은 모빌리티 서비스 결제를 위한 필수 기능!

티맵 앱에는 대리운전, 킥보드, 전기차 충전, 주차, 픽업 같이 앱 내 결제를 필요로 하는 많은 서비스들이 있습니다. 티맵 결제 서비스는 앱 내 결제를 위해서 신용카드를 등록할 때 OCR(Optical Character Recognition, 광학 문자 인식) 기능을 제공하는데요. OCR은 ‘텍스트 이미지를 기계가 읽을 수 있는 텍스트 포맷으로 변환하는 과정’을 의미합니다. 티맵에서 쓰이는 것처럼 흔히 모바일 기기의 카메라로 카드 번호 인식 및 신분증 인식을 하는데 쓰이죠.


OCR 기능은 유료로 제공하는 솔루션을 구매하여 간편히 적용할 수도 있고, OS에서 제공하는 library를 이용하여 직접 구현할 수도 있습니다.


애플은 iOS Vision framework에서 텍스트 인식 기능을 제공하고 있고, 구글은 Google ML kit에서 안드로이드 및 iOS에서 사용할 수 있는 텍스트 인식 기능을 제공하고 있습니다.


이번 브런치에서는 애플, 구글에서 제공하는 라이브러리뿐만 아니라, 안드로이드의 경우엔 그 외의 오픈 소스 라이브러리들을 이용하여 신용카드의 번호를 인식하는 OCR 기능을 구현하는 법을 소개해 보겠습니다.


Chap1. Android 앱에 OCR 적용하기


1. Google ML Kit

Google ML Kit는 머신러닝에 대해 숙련되지 않은 개발자라도 그 기능을 이용할 수 있게 해주는 SDK입니다. 여기서는 ML Kit의 텍스트 인식 API를 사용했습니다.


사용법

1. 의존성을 추가해줍니다. (build.gradle (:app))

2. cameraProvider를 가져온 후, listener에서 사용할 useCase와 bind 해줍니다.

3. 카메라 프리뷰를 생성하고 LifeCycle에 bind 해줍니다.

4. 프리뷰를 분석할 analyzer를 생성하고 LifeCycle에 bind 해줍니다.

5. 결과값을 받아올 Listener 코드를 작성합니다. 여기서는 간단히 textView에 결과값을 넣어주었습니다.

결과

세 가지 방식 중 가장 빠르고 정확합니다. 카드에 적힌 모든 텍스트를 인식합니다. 양각으로 새겨진 숫자의 경우 인식이 잘 되지 않아 숫자가 알파벳으로 인식되는 경우가 많으나 숫자로 인식되는 경우도 있었습니다. 카드 번호가 모두 숫자로 인식되는 순간을 구분해내어 결과값을 넘기는 식으로 개발 진행하였습니다.


2. Card.IO

Google ML kit가 등장하기 전 가장 많이 사용되던 OCR Library 입니다.


사용법

1. 의존성을 추가해줍니다. (build.gradle (:app))

2. 결과값을 얻어온 후 다시 이 액티비티로 돌아왔을 때의 코드를 작성합니다. 이 예제에서는 카드 번호만 얻어와서 textView에 넣어주고 촬영한 이미지와 카드 타입 이미지를 표시해주었습니다.

3. 설정값들을 intent의 extra로 넣어주고 CardIOActivity로 이동하는 intent를 실행합니다.

결과

세 가지 방식 중 두번째로 빨랐습니다. 카드에 적힌 텍스트 중 양각으로 새겨진 텍스트만 인식합니다.


3. Tesseract

1984~1994년에 HP 연구소에서 개발된 오픈 소스 OCR 엔진입니다.


사용법

1. native C++ 프로젝트로 시작해야 합니다.

2. openCV sdk를 import 하여 사용해야 합니다. Releases · opencv/opencv

3. 각 언어별 학습 데이터를 다운로드한 후(GitHub - tesseract-ocr/tessdata: Trained models with support for legacy and LSTM OCR engine ) assets 폴더를 생성하여 저장합니다.

4. 의존성을 추가합니다. (build.gradle (:app))

5. Google ML Kit와 동일한 방식으로 preview를 bind 해줍니다.

6. TessBaseAPI 객체를 생성하고 언어 파일의 경로를 아래와 같이 지정한 후, TessBaseAPI 객체를 initialize 합니다.

7. Tesseract의 경우 사진을 찍은 후 분석하기 때문에 사진을 찍고 결과값을 받은 후의 코드를 작성합니다.

결과

세 가지 방식 중 인식률이 가장 떨어지고 인식 시간이 길었습니다.


Android 전체 코드

Reference

1.GitHub - googlesamples/mlkit: A collection of sample apps to demonstrate how to use Google's ML Kit APIs on Android and iOS

2. Recognize text in images with ML Kit on Android  |  Google Developers

3. Implement a preview  |  Android Developers

4. Image analysis  |  Android Developers

5. Image capture  |  Android Developers

6.GitHub - card-io/card.io-Android-SDK: card.io provides fast, easy credit card scanning in mobile apps

7.Android에서 Tesseract 사용하기 for OCR


Chap2. iOS 앱에 OCR 적용하기


1. iOS Vision framework

iOS는 컴퓨터 vision의 다양한 알고리즘을 수행하는 Vision framework를 제공하고 있습니다. Vision framework은 사진, 영상으로부터 얼굴인식, 문자인식, 바코드 인식 등의 기능을 API로 제공해주며 OS11 이상부터 사용할 수 있습니다.

Apple Developer Documentation

사용법

1. ImageAnalyzer class 만들기

먼저, 이미지로부터 카드번호를 인식하는 ImageAnalyzer class를 먼저 만듭니다.

2. Vision framework을 import 합니다.

3. VNRecognizeTextRequest 를 생성합니다.

VNRecognizeTextRequest는 이미지에서 text를 추출하는 vision framework의 API입니다. text 추출 결과를 받기위한 completionHandler 를 인자로 넣어줍니다.

4. 이미지 분석 요청을 하는 analyze 함수를 만듭니다.

VNImageRequestHandler는 이미지를 받아 분석 요청을 처리하는 객체입니다. 카메라, 갤러리를 통해 입력받은 CGImage를 함수의 인자로 넣습니다. CGImage를 입력값으로 VNImageRequestHandler를 생성합니다. VNImageRequestHandler.perform 으로 이미지 분석 요청을 합니다.

5. 추출된 Text를 처리합니다.

추출된 결과는 VNRecognizeTextRequest 생성 시 넣은 completionHandler로 전달됩니다. 추출된 results는 이미지에서 인식한 여러 개의 텍스트 object들을 array로 제공합니다. 각각의 object에는 문자, 위치, 정확도 등의 정보가 포함되어 있습니다.


신용카드에는 카드번호, 만료 날짜 외에 이름, 브랜드, 카드 종류 등 다양한 문자들이 있습니다. 추출된 object array에는 이런 문자들이 모두 포함되어 있습니다. 우리가 필요한 카드번호와 만료 날짜만 걸러내기 위해 string의 정규식을 사용합니다. 신용카드는 숫자, ‘-’, ‘ ‘ 문자로 된 15~19자리의 문구를, 만료 날짜는 2개 숫자 + ‘/’ + 2개 숫자로 된 문구를 정규식으로 사용합니다. 추출된 results 문구들에서 정규식 패턴에 맞는 카드번호, 만료 날짜 문구 후보를 찾아냅니다.

6. View Controller에 ImageAnalyzer 적용

앞에서 만든 ImageAnalyzer를 카드 스캔 ViewController에 적용합니다. 티맵은 아래와 같은 UI를 제공하고 있습니다. 상단에는 flash 버튼, 닫기 버튼을 하단에는 사용자가 번호를 직접 입력할 수 있는 버튼을 가운데는 카드를 스캔하는 camera preview가 있습니다. Preview 영역에 신용카드가 들어오게 하면 카드번호가 인식이 됩니다. 카드번호 인식의 정확도를 높이기 위해 티맵은 video stream에서 이미지를 연속으로 받아 동일한 번호가 여러 번 인식되는 경우 인식 완료로 처리합니다.

7. Video stream의 구현

AVCaptureVideoDataOutputSampleBufferDelegate을 사용하여 아래처럼 구현합니다.

a.AVCaptureVideoDataOutputSampleBufferDelegate의 captureOutput으로 현재 보이는 video의 스틸 이미지 sampleBuffer를 받습니다.

b.sampleBuffer를 cgImage 변환합니다.

c.preview UI의 카드 스캔 영역의 크기에 맞게 cgImage를 crop 시킵니다.

d.crop 이미지를 analyze(image: CGImage) 요청합니다.

e.analyze 된 카드번호가 동일한 번호로 N(2~3) 회 나오면 완료로 처리합니다.


2. VisionKit 사용하기

카드 스캔을 위한 별도의 UI 요구사항이 없다면 iOS에서 제공하는 VisionKit을 사용할 수 있습니다.


VisionKit은 iOS13부터 제공이 되며, VNDocumentCameraViewController는 문서를 스캔할 수 있는 아래와 같은 UI를 제공합니다. 신용카드를 카메라 앞에 놓으면 자동으로 화면이 캡처가 됩니다. 캡처 후 하단에 표출되는 ‘저장' 버튼을 누르면 VNDocumentCameraViewControllerDelegate를 통해 캡처된 이미지가 전달됩니다.


3. Google ML Kit

 Recognize text in images with ML Kit on iOS  |  Google Developers


사용법

1. pod에 TextRecognition을 추가합니다.

2. library를 import 합니다.

3. ImageAnalyzer의 analyze 부분을 MLKit으로 구현합니다.


마치며


아쉽게도 Vision framework, MLKit와 그 외의 라이브러리들을 이용한 OCR 기능은 요구하는 성능을 만족하지 못해 서비스에 적용은 힘들었습니다 신용카드 번호 부분의 배경에 복잡한 이미지가 포함되거나, 카드번호의 코팅이 벗겨지거나 하는 경우 인식률이 떨어졌습니다.


Vision framework, MLKit는 문자인식 외에도 다양한 vision 알고리즘을 제공하고 있습니다. 티맵의 졸음운전 감지 기능도 vision framework을 을 사용하고 있습니다. 티맵에 Vision을 사용하는 좀 더 다양한 기능들이 추가될 수 있으면 좋겠습니다.


매거진의 이전글 AWS Graviton2 출시 후 바로 도입해본 후기

작품 선택

키워드 선택 0 / 3 0

댓글여부

afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari