Amazon Rekognition API를 이용하여 이미지에서 텍스트의 영역을 감지하고 문자 인식(OCR)을 하는 방법에 대해 설명드리도록 하겠습니다. Google이나 Microsoft, Amazon 과 같은 회사의 공통점은 엄청난 양의 이미지 데이타를 보유하고 있다는 것입니다. 그리고 그들은 이미 이런 데이터를 활용하여 믿을 수 없을 정도의 높은 성능의 OCR 모델을 만들었고 API로 제공하고 있습니다.

1. Amazon Rekognition API 키 발급

Amazon Rekognition OCR API 수행하기 위해서는 먼저 Amazon Rekognition에 대한 자격 증명 키 발급이 필요합니다. AWS 계정이 필요하며 계정이 없다면 계정 생성이 필요합니다. 계정 생성 시에 신원을 확인하기 위해 지불 방법과 함께 이메일 주소, 성과 이름과 같은 세부 정보를 제공해야 합니다. 이미 AWS 계정이 있다면 로그인 후 진행하시면 됩니다.

계정 생성 및 로그인이 완료되면 AWS 콘솔로 이동합니다.

이제 AWS 엑세스 키를 얻기 위해 AWS IAM 콘솔로 이동합니다.

IMA 콘솔로 이동이 되면 우측 빠른 링크 영역에서 [내 보안 자격 증명] 을 클릭합니다. 사용자에 따라 다른 View로 나타날 수 있으니 참고하세요.

보안 자격 증명 페이지에서 [엑세스 키(엑세스 키 ID 및 비밀 엑세스 키)] 선택 후 [새 엑세스 키 만들기]를 선택합니다. [키 파일 다운로드]를 클릭하여 파일을 다운로드하여 안전한 곳에 보관하시기 바랍니다. 엑세스 키와 보안 엑세스 키는 Amazon Rekognition OCR API를 사용하기 위해 필요합니다.

2. Amazon Rekognition API 개발 환경 구성

Python용 AWS SDK인 boto3패키지 설치가 필요합니다. pip를 이용하여 간단히 설치가 가능합니다.

pip install boto3

3. Amazon Rekognition API Script 구현

Import Packages

import numpy as np
import platform
from PIL import ImageFont, ImageDraw, Image

import cv2
import boto3

Jupyter Notebook 또는 Colab에서 이미지를 확인하기위한 Function

def plt_imshow(title='image', img=None, figsize=(8 ,5)):
    plt.figure(figsize=figsize)
 
    if type(img) == list:
        if type(title) == list:
            titles = title
        else:
            titles = []
 
            for i in range(len(img)):
                titles.append(title)
 
        for i in range(len(img)):
            if len(img[i].shape) <= 2:
                rgbImg = cv2.cvtColor(img[i], cv2.COLOR_GRAY2RGB)
            else:
                rgbImg = cv2.cvtColor(img[i], cv2.COLOR_BGR2RGB)
 
            plt.subplot(1, len(img), i + 1), plt.imshow(rgbImg)
            plt.title(titles[i])
            plt.xticks([]), plt.yticks([])
 
        plt.show()
    else:
        if len(img.shape) < 3:
            rgbImg = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
        else:
            rgbImg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
        plt.imshow(rgbImg)
        plt.title(title)
        plt.xticks([]), plt.yticks([])
        plt.show()

OpenCV의  putText 를 이용하여 한글을 출력하는 경우 한글이 깨지는 문제를 해결하기 위한 Funtion

def put_text(image, text, x, y, color=(0, 255, 0), font_size=22):
    if type(image) == np.ndarray:
        color_coverted = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = Image.fromarray(color_coverted)
 
    if platform.system() == 'Darwin':
        font = 'AppleGothic.ttf'
    elif platform.system() == 'Windows':
        font = 'malgun.ttf'
        
    image_font = ImageFont.truetype(font, font_size)
    font = ImageFont.load_default()
    draw = ImageDraw.Draw(image)
 
    draw.text((x, y), text, font=image_font, fill=color)
    
    numpy_image = np.array(image)
    opencv_image = cv2.cvtColor(numpy_image, cv2.COLOR_RGB2BGR)
 
    return opencv_image

자신의 엑세스 키와 보안 엑세스 키, Resion 값으로 클라이언트를 초기화합니다. 엑세스 키와 보안 엑세스 키 값은 위에 설명한 것처럼 AWS IAM 콘솔의 보안 자격 증명 페이지에서 확인 하실 수 있습니다. 만약 'ClientError: An error occurred (UnrecognizedClientException) when calling the DetectText operation: The security token included in the request is invalid.' 에러가 발생한다면 엑세스 키 값을 잘못 입력하였거나, 비활성화 또는 삭제된 키일 수 있습니다. 이런 경우 다시 보안 자격 증명 페이지로 이동하여 [새 액세스 키 만들기] 를 눌러 생성하시고 그 값으로 클라이언트를 초기화 하시면 됩니다. Resion 정보는 참고 가이드 페이지에서 확인 하실 수 있습니다. (저는 한국이기때문에 "ap-northeast-2" 를 입력하여 수행했습니다.)

ACCESS_KEY = "<YOUR_ACCESS_KEY>"
SECRET_KEY = "<YOUR_SECRET_KEY>"
REGION = "<YOUR_REGION>"

client = boto3.client("rekognition", aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY, region_name=REGION)

Load Image

이미지는 바이너리 객체로 변환하여  load 합니다.

path = 'asset/images/test_image9.jpg'
imageData = open(path, "rb").read()

Request to Amazon Rekognition API

 Amazon Rekognition API를 호출하면 결과 값을 받을 수 있습니다.

response = client.detect_text(Image={"Bytes": imageData})
detections = response["TextDetections"]

Check Result

 

img = cv2.imread(path)
roi_img = img.copy()
    
(h, w) = img.shape[:2]
for detection in detections:
    text = detection["DetectedText"]
    textType = detection["Type"]
    poly = detection["Geometry"]["Polygon"]
    
    if "line" == textType.lower():
        tlX = int(poly[0]["X"] * w)
        tlY = int(poly[0]["Y"] * h)
        trX = int(poly[1]["X"] * w)
        trY = int(poly[1]["Y"] * h)
        brX = int(poly[2]["X"] * w)
        brY = int(poly[2]["Y"] * h)
        blX = int(poly[3]["X"] * w)
        blY = int(poly[3]["Y"] * h)

        pts = ((tlX, tlY), (trX, trY), (brX, brY), (blX, blY))
        topLeft = pts[0]
        topRight = pts[1]
        bottomRight = pts[2]
        bottomLeft = pts[3]

        cv2.line(roi_img, topLeft, topRight, (0,255,0), 2)
        cv2.line(roi_img, topRight, bottomRight, (0,255,0), 2)
        cv2.line(roi_img, bottomRight, bottomLeft, (0,255,0), 2)
        cv2.line(roi_img, bottomLeft, topLeft, (0,255,0), 2)

        roi_img = put_text(roi_img, text, topLeft[0], topLeft[1] - 10, font_size=30)

        print(text)

plt_imshow(["Original", "ROI"], [img, roi_img], figsize=(16, 10))

더보기
thank you for coming

일단 결과를 보면 영어는 잘 인식하였지만 한글은 전혀 인식하지 못했습니다. 다른 이미지로 수행해 보았을 때도 결과는 마찬가지입니다. 

더보기
مار
KT
Bus
TAXI
M
Taxi
(4)

단순히 두 이미지의 결과만 놓고 본다면 다른 API (Google Cloud Vision API, Microsoft Cognitive Services API)에 비해 자동 언어 식별과 다국어 문서에 대한 인식율은 낮아 보입니다.

반응형