2020년 6월 20일 토요일

카카오, 네이버 구글 OCR 테스트


그림에서 글자를 추출하는 것을 OCR (Optical Character Recognition)이라고 합니다.   대표적으로 ABBYY라는 프로그램이 유명하지만 최근에는  카카오,  네이버, 구글에서 API 형태로도 가능한 OCR 프로그램을 내놓았습니다.   이들 OCR는 처리량에 비례하는 요금제를 채택하고 있어 테스트하기에는  재정적인 부담이 전혀 없습니다.

테스트 대상은  책 사진입니다. 책 사진에서 제목을 뽑으려고 합니다. 



카카오 OCR API  https://developers.kakao.com/docs/latest/ko/vision/common에서 사용자와 서비스를  등록하고 아래 파이썬 프로그램으로 테스트합니다.   프로그램에 나온 appkey는 등록 후에 받아야 합니다.  이 프로그램도 위 사이트에서 가져 왔는데  function main만 편집하고 나머지는 그대로입니다.



import json

import cv2
import requests
import sys

LIMIT_PX = 1024
LIMIT_BYTE = 1024*1024  # 1MB
LIMIT_BOX = 40

appkey = "4c65b9287b7b7a53fb3e211a9268"

def kakao_ocr_resize(image_path: str):

    image = cv2.imread(image_path)
    height, width, _ = image.shape

    if LIMIT_PX < height or LIMIT_PX < width:
        ratio = float(LIMIT_PX) / max(height, width)
        image = cv2.resize(image, None, fx=ratio, fy=ratio)
        height, width, _ = height, width, _ = image.shape

        # api 사용전에 이미지가 resize된 경우, recognize시 resize된 결과를 사용해야함.
        image_path = "{}_resized.jpg".format(image_path)
        cv2.imwrite(image_path, image)

        return image_path
    return None


def kakao_ocr_detect(image_path: str, appkey: str):
    API_URL = 'https://kapi.kakao.com/v1/vision/text/detect'

    headers = {'Authorization': 'KakaoAK {}'.format(appkey)}

    image = cv2.imread(image_path)
    jpeg_image = cv2.imencode(".jpg", image)[1]
    data = jpeg_image.tobytes()

    return requests.post(API_URL, headers=headers, files={"file": data})


def kakao_ocr_recognize(image_path: str, boxes: list, appkey: str):
    API_URL = 'https://kapi.kakao.com/v1/vision/text/recognize'

    headers = {'Authorization': 'KakaoAK {}'.format(appkey)}

    image = cv2.imread(image_path)
    jpeg_image = cv2.imencode(".jpg", image)[1]
    data = jpeg_image.tobytes()

    return requests.post(API_URL, headers=headers, files={"file": data}, data={"boxes": json.dumps(boxes)})

resize_impath = kakao_ocr_resize("book.jpg")
if resize_impath is not None:
    image_path = resize_impath
    print("원본 대신 리사이즈된 이미지를 사용합니다.")

output = kakao_ocr_detect(image_path, appkey).json()
print("[detect] output:\n{}\n".format(output))

boxes = output["result"]["boxes"]
boxes = boxes[:min(len(boxes), LIMIT_BOX)]
output = kakao_ocr_recognize(image_path, boxes, appkey).json()
print("[recognize] output:\n{}\n".format(json.dumps(output, sort_keys=True, indent=2)))


결과는 다소 실망입니다.   한글을 전혀 인식하지 못해서 이상한 영문자를 출력하고 있습니다.



다음은 네이버  OCR입니다.   사용자와 서비스는 등록은  https://www.ncloud.com/product/aiService/ocr 에서  합니다.    네이버에는  파이썬 프로그램 샘플이 없습니다.  대신 postman이라는  간단한 프로그램을 통해 결과를 확인할 수 있습니다.  아래와 같이 URL 을 지정해서 API를 호출하고  json 파일에 인식해야 할 사진 파일을 지정합니다.  Postman는 따로 설치가 필요합니다.



문자 인식에 대한 결과가 다음입니다.



제목이  정원가의 열두렐로 오류가 있지만 카카오 OCR 보다 나아 보입니다.

다음은 구글 OCR입니다.    https://cloud.google.com/vision/docs/ocr?hl=ko  에서 사용자와 서비스를 등록합니다.  등록 후에  Credential 파일을 다운 받고 환경 변수 GOOGLE_APPLICATION_CREDENTIALS으로 이 파일을 지정합니다.   아래  테스트 프로그램은 구글에서 제공합니다.   실행 전에 “pip install google-cloud-vision”으로 모듈 설치가 필요합니다.


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)))


detect_text("book.jpg")


아래는 위 실행 결과 일부입니다. 



엉뚱한 문자가 있기는 하지만  OCR의 인식 결과는 나쁘지 않습니다.  제목 정원가의 열두달을 정확하게 출력합니다.

이용 요금도 구글 OCR이 네이버보다 싸기 때문에 당분간 구글 OCR를 이용하려고 합니다.

댓글 없음:

댓글 쓰기