👨🏽‍💻

ch3 - 7. Google API 활용

vision api 글자인식의 원리, OCR

OCR 이란 무엇일까?

OCR 이란 Optional Character Reader(or Recognition) 의 줄임말로서 한국어로 하면 광학 문자 인식 입니다. 사람이 쓰거나 기계로 인쇄한 문자의 이미지를 통해 기계가 읽을 수 있는 문자로 변환하는 것이죠.
인공지능의 한 분야로서 현재 빠르게 발전하고 있습니다. 우리 실생활에서도 활용이 되고 있는데 주차장에서 자동차 번호판을 이 방법을 통해 각 차량을 구분하고 있습니다. 이 외에도 활용도에 따라 가치는 무궁무진할거라고 생각합니다. 이제 OCR이 어떤 원리로 문자를 인식하는지 알아보도록 하겠습니다.
 

OCR의 원리를 알아보자

뒷 부분에서 다루겠지만 google api를 사용하게 된다면 이 과정이 어떤 식으로 동작하는지는 전혀 알 필요가 없습니다. 모든 건 구글이 알아서 해주기 때문이죠. 그래도 대략적이라도 원리를 알아야한다고 생각하기 때문에 대략적인 클 틀을 설명해드리도록 하겠습니다.

문자 이미지 인식

이미지가 주어졌을 때, 문자가 어느 부분인지를 인식해야합니다. 이 때는 색을 통해서 구분을 해줍니다. 문자의 색깔이 아닌 부분을 모두 바탕으로 만들어주어, 글자를 인식하게 됩니다.
notion imagenotion image
notion imagenotion image
 

이미지 나누기

문자가 있는 부분을 인식했다면, 이제 이 부분을 개별 알파벳으로 나눠줘야 합니다.
 

크기가 같은 문자 만들기

각각의 알파벳 이미지들을 얻었지만 현재 각 알파벳들은 크기가 제각각 입니다. 뒤에서 다시 한 번 언급하겠지만 연산을 위해 이 이미지들을 일정 크기로 변환시켜줍니다.

이미지를 데이터로 바꿔주기

아직까지 우리가 가진 데이터는 단순한 이미지에 불과합니다. 이를 데이터로 바꿔주는 과정이 필요한데, 그 방법으로 문자가 있는 검은색 부분은 1로, 흰 색 부분을 0으로 바꿔줍니다.
notion imagenotion image
다음 이미지가 어떤 문자로 보이시나요? 아마 '1' 인 걸 모두가 알 수 있을 겁니다. 사실 위 이미지는 0과 1로만 이루어진 이미지이며, 이 두 수만 가지고도 시각적으로 쉽게 어떤 문자인지를 알 수 있습니다.

이미지 인식하기

이미지를 인식하기 위해서는 정답 이미지가 있어야 될 것입니다. 정답이미지는 마찬가지로 0과 1로 이루어져 있으며 어떤 철자인지 라벨링이 되어있어야 합니다. 그렇다면 정답이미지와 확인하고 싶은 이미지를 어떤 과정을 통해 비교하는 걸까요?
바로 XOR 연산을 이용합니다. XOR 연산은 아래 테이블과 같이 같으면 0, 다르면 1을 출력합니다.
notion imagenotion image
 
이 연산자를 통해 어떤 마법을 부릴 수 있을까요? 다른 철자에 대한 이미지에 대해서는 XOR를 하면 알아볼 수 없는 괴상한 이미지가, 같은 철자에 대해서는 0으로 가득찬 배경이 나타나게 됩니다.
 
notion imagenotion image
OCR은 다음과 같은 방식으로 철자를 인식하게 됩니다.
 

한글을 인식하기 어려운 이유

이런 방식 때문에 아쉬움이 하나 남습니다. 바로 한글을 인식하기가 쉽지 않다는 점이죠. 알파벳 같은 경우에는 소문자와 대문자를 합쳐 52개의 정답이미지 중 구분을 해주면 되지만, 한글은 자음과 모음을 조합하여 하나의 철자를 만들기에는 수 없이 많은 경우의 수가 존재합니다. 그 만큼 오차가 일어날 일도 많게 되는 것이죠.
 

Google vision api

놀랍게도 이 모든 과정을 google이 해줍니다. 정확히는 google vision api가 해주는 것이죠. 함께 이 과정을 알아보도록 하겠습니다.
 

vision API 를 활용한 글자인식 실습

사전준비

vision API 뿐만 아니라 다른 google API를 사용하기 위해서도 사전준비가 필요합니다. 이에 대해 알아보도록 하겠습니다. 먼저 아래 url 로 접속합니다.
이 곳에서 우리는 사용자 인증 정보를 만들고 API 를 사용할 수 있는 key 를 받을 수 있습니다.
notion imagenotion image
좌측 메뉴바에서 사용자 인증 정보 로 이동하면 사용자 인증 정보 만들기 라는 버튼을 찾을 수 있습니다.
notion imagenotion image
버튼을 클릭하면 인증 정보를 만들 수 있는 다양한 방식을 선택할 수 있습니다. 서비스 계정 키를 이용해서 만들어보도록 하겠습니다.
notion imagenotion image
계정이름과 계정 ID를 적어주고 키 유형은 JSON 을 이용해서 받도록 하겠습니다. 이 때 역할은 선택하지 않습니다.
notion imagenotion image
그 결과, json 형식의 파일이 하나 다운 받아졌습니다. 이 파일을 key로서 사용하게 될 것입니다. 이 key 만 있다면 다른 사용자도 cloud과 통신할 수 있으므로 노출해서는 안됩니다.
notion imagenotion image
키가 만들어진 것을 확인했다면 local 로 넘어와보도록 하겠습니다. 우선 vision API 를 사용하기 위해서 이 라이브러리를 설치해야합니다. pip 를 통해서 설치하도록 하겠습니다.
pip install google-cloud-vision
notion imagenotion image
설치가 다 완료되었으면 작업 공간을 만들어주겠습니다. 바탕화면에 Vision API 라는 디렉토리를 만들고 이 안에 아까 다운받았던 json 파일도 가져오도록 하겠습니다.
terminal 에서 현재 경로를 확인해보면 다음과 같습니다.
pwd #/Users/rkdalstjd9/desktop/VisionAPI
이제 API 를 사용할 VisionAPI.py 를 만들고 환경변수를 설정해주도록 하겠습니다. terminal에서 아래의 명령어를 입력해줍니다.
export GOOGLE_APPLICATION_CREDENTIALS="/Users/rkdalstjd9/desktop/VisionAPI/ VisionAPI-9a8f1b0d454a.json"
위에서 확인한 현재 작업공간의 경로에 아까 다운받은 json 파일을 지정해줍니다. 그렇게 때문에 위의 명령어는 사용자마다 다를 것입니다.
 

실습하기

드디어 사전준비가 모두 끝났습니다. 이제 API 가 잘 동작하는지 확인해보도록 하죠.
import io def detect_text(path): from google.cloud import vision client = vision.ImageAnnotatorClient() with io.open(path, 'rb') as image_file: content = image_file.read() image = vision.types.Image(content=content)
먼저 detect_text 라는 함수를 정의합니다. 파리미터로 이미지 파일의 경로를 받아 그 이미지 내의 글자를 인식하게 되죠. 여기까지는 이미지를 vision API가 읽을 수 있는 형태로 가공해주는 과정입니다.
 
response = client.text_detection(image=image) texts = response.text_annotations
text_dection 으로 인해 정보를 추출합니다.
  • respose 에는 상세한 정보들이 저장됩니다. 어느 언어로 인식 했는지 부터 문장 별, 단어 별, 각 철자 별 어떻게 인식을 하였는지, 이미지에서 위치는 어디에 있는지 상세 정보들이 담기게 됩니다.
  • texts 에는 response 에서 내용을 좀 더 간추립니다. 철자는 제외하고 문장과 단어에 대한 정보만 담기게 됩니다.
 
for text in texts: print('\n"{}"'.format(text.description)) vertices = (['({},{})'.format(vertex.x, vertex.y) for vertex in text.bounding_poly.vertices]) print('bounds: {}'.format(','.join(vertices)))
그 후 texts 에 담긴 정보의 가시성을 높이기 위해 약간의 가공을 해줍니다.
 
import os file_name = os.path.join( os.path.dirname(__file__), 'Hello_world.png') detect_text(file_name)
마지막으로 이미지의 경로를 설정하고 함수를 실행시켜줍니다.
 
전체코드는 다음과 같습니다.
import os, io def detect_text(path): from google.cloud import vision client = vision.ImageAnnotatorClient() with io.open(path, 'rb') as image_file: content = image_file.read() image = vision.types.Image(content=content) response = client.text_detection(image=image) texts = response.text_annotations print('Texts:') for text in texts: print('\n"{}"'.format(text.description)) vertices = (['({},{})'.format(vertex.x, vertex.y) for vertex in text.bounding_poly.vertices]) print('bounds: {}'.format(','.join(vertices))) file_name = os.path.join( os.path.dirname(__file__), 'Hello_world.png') detect_text(file_name)
 
이미지와 이미지의 결과는 다음과 같습니다.
 
notion imagenotion image
Texts: "Hello World!" bounds: (48,52),(351,52),(351,91),(48,91) "Hello" bounds: (48,52),(170,52),(170,91),(48,91) "World!" bounds: (185,52),(351,52),(351,91),(185,91)
이미지 내에서 철자의 위치를 각 꼭지점의 좌표를 통해서 표시를 해줍니다. 좌측 하단부터 시계 반대 방향으로 좌표를 나타냅니다.
 
다행스럽게도 영어 외의 다른 언어들도 지원을 합니다. 지원하는 언어는 아래 url에서 확인할 수 있습니다.
 

Google Cloud vision api 활용한 사진 물체 인식

  • 주의 : 코드에 따라 금액 결제가 진행 될 수 있습니다. 항상 결제 규정을 확인해주세요.
  • Google Cloud vison api를 사용하여 물체 인식하기
  • 단 다운 받은 로컬에 저장되어있는 이미지여야 합니다.
  • 사진 인식에는 컴퓨터에 저장되어있는 사진에 대한 인식과 원격으로의 인식 등 여러가지가 있습니다. 같이 진행해볼 것은 컴퓨터에 저장되어있는 이미지에 대한 물체 종류 인식입니다.
  • Google에도 여러가지 사진 인식 API가 있습니다. 본 문서에서는 그 중 하나를 다룹니다.

1 단계

구글 기본 검색창에 Google Cloud 검색 후 회원가입 합니다.
결제수단에서 카드를 등록합니다. 사진을 월 100장 내로 사용할 일반적인 개인 사용자라면 5달러 이상 결제 될 일이 없습니다. 하지만 사진의 장수 또는 코드의 요청 횟수가 많아지면 금액이 커질 수 있으니 설정에서 결제 한도나 알림 설정 하시는 것을 권장합니다. 금액 결제 측면에서는 규정을 정독하신 후 사용하시길 바랍니다.
Google Cloud Platform 메뉴에서 api -> 라이브러리 에서 cloud vision api 검색한 후 사용 설정합니다.
notion imagenotion image
이 과정에서 사용자 인증 정보를 만들라고 할 수 있습니다. 역할 설정을 선택하지 않은 채 만들어주면 됩니다.
 

2 단계

아래 사진의 Google Cloud Platform 에 들어 간 후 우측 상단의 빨간 부분의 콘솔 버튼을 클릭한 후
 
notion imagenotion image
 
export GOOGLE_APPLICATION_CREDENTIALS= "아까받은 API키 파일이 있는 전체 경로를 입력합니다, 경로의 끝에는 json파일도 있어야합니다."
다음 코드는 기본 설정 완료 후 API를 이용하여 실질적으로 사진을 인식하는 과정의 코드입니다.
( 앞 챕터에서 설명한 Jupyter notebook을 사용하였습니다. )
import io import os from google.cloud import vision from google.cloud.vision import types from PIL import Image image_path = 'sample/bigstock-Group-Of-Animals-34563776.jpg' #사진의 파일 경로를 입력합니다. Image.open(image_path) with open(image_path, 'rb') as image_file: content = image_file.read() image = vision.types.Image(content=content) objects = client.object_localization( image=image).localized_object_annotations print('Number of objects found: {}'.format(len(objects))) for object_ in objects: print('\n{} (confidence: {})'.format(object_.name, object_.score)) print('Normalized bounding polygon vertices: ') for vertex in object_.bounding_poly.normalized_vertices: print(' - ({}, {})'.format(vertex.x, vertex.y))
 
notion imagenotion image
 
위 사진에 대한 실행 코드의 결과값입니다.
#위 코드 실행시 결과값입니다. Number of objects found: 6 #사진에서 찾은 물체의 개수를 의미합니다. Animal (confidence: 0.7332704663276672) #사진 분석 결과의 신뢰도를 의미합니다. Normalized bounding polygon vertices: #사진의 위치를 의미합니다. - (0.24000002443790436, 0.2442353069782257) - (0.5936470627784729, 0.2442353069782257) - (0.5936470627784729, 0.5710588693618774) - (0.24000002443790436, 0.5710588693618774) Zebra (confidence: 0.7256933450698853) Normalized bounding polygon vertices: - (0.02047058939933777, 0.43835294246673584) - (0.28470590710639954, 0.43835294246673584) - (0.28470590710639954, 0.7030588984489441) - (0.02047058939933777, 0.7030588984489441) Elephant (confidence: 0.710447371006012) Normalized bounding polygon vertices: - (0.24000002443790436, 0.2442353069782257) - (0.5936470627784729, 0.2442353069782257) - (0.5936470627784729, 0.5710588693618774) - (0.24000002443790436, 0.5710588693618774) Animal (confidence: 0.672944962978363) Normalized bounding polygon vertices: - (0.07152940332889557, 0.5578823685646057) - (0.34658825397491455, 0.5578823685646057) - (0.34658825397491455, 0.9101176261901855) - (0.07152940332889557, 0.9101176261901855) Lion (confidence: 0.6563335657119751) Normalized bounding polygon vertices: - (0.07152940332889557, 0.5578823685646057) - (0.34658825397491455, 0.5578823685646057) - (0.34658825397491455, 0.9101176261901855) - (0.07152940332889557, 0.9101176261901855) Animal (confidence: 0.5748072266578674) Normalized bounding polygon vertices: - (0.02047058939933777, 0.43835294246673584) - (0.28470590710639954, 0.43835294246673584) - (0.28470590710639954, 0.7030588984489441) - (0.02047058939933777, 0.7030588984489441)
이외에도 랜드마크 인식에 대한 API, 인물 인식에 대한 API 등 여러가지가 있습니다. 사용자의 목적과 환경에 따른 적절한 API를 활용하면 됩니다.