졸업프로젝트 🎓

[ 졸업프로젝트 ] 카카오 vision API(OCR) 사용하기 feat.Colab

컴공생 C 2021. 3. 3. 00:45
반응형

카카오 좋은 기업이네..

사용할 이미지

결과 화면 

[OCR] output:{ "result": [ { "boxes": [ [ 132, 249 ], [ 177, 249 ], [ 177, 288 ], [ 132, 288 ] ], "recognition_words": [ "12" ] }, { "boxes": [ [ 196, 254 ], [ 244, 253 ], [ 244, 277 ], [ 196, 278 ] ], "recognition_words": [ "EBS" ] }, { "boxes": [ [ 250, 252 ], [ 343, 252 ], [ 343, 278 ], [ 250, 278 ] ], "recognition_words": [ "수능완성" ] }, { "boxes": [ [ 352, 250 ], [ 446, 246 ], [ 448, 274 ], [ 354, 279 ] ], "recognition_words": [ "수학영역" ] }, { "boxes": [ [ 456, 248 ], [ 502, 248 ], [ 502, 274 ], [ 456, 274 ] ], "recognition_words": [ "나형" ] } ] }

 

전체 코드
import json
import time
import cv2
import requests
import sys
from google.colab.patches import cv2_imshow
LIMIT_PX = 1024
LIMIT_BYTE = 1024*1024  # 1MB
LIMIT_BOX = 40


def kakao_ocr_resize(image_path: str):
    """
    ocr detect/recognize api helper
    ocr api의 제약사항이 넘어서는 이미지는 요청 이전에 전처리가 필요.

    pixel 제약사항 초과: resize
    용량 제약사항 초과  : 다른 포맷으로 압축, 이미지 분할 등의 처리 필요. (예제에서 제공하지 않음)

    :param image_path: 이미지파일 경로
    :return:
    """
    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(image_path: str, appkey: str):
    """
    OCR api request example
    :param image_path: 이미지파일 경로
    :param appkey: 카카오 앱 REST API 키
    """
    API_URL = 'https://dapi.kakao.com/v2/vision/text/ocr'

    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={"image": data})


def main():
    if len(sys.argv) != 3:
        print("Please run with args: $ python example.py /path/to/image appkey")
    image_path, appkey = '/content/drive/MyDrive/ts/swpg.png', '발급받은 APP키'
    white = [255,255,255]
    img=cv2.imread(image_path)
    constant= cv2.copyMakeBorder(img,200,100,100,100,cv2.BORDER_CONSTANT,value=white)
    image_path='/content/drive/MyDrive/ts/swpg.jpg'
    cv2.imwrite(image_path, constant)
    cv2_imshow(constant)
    time.sleep(2)
    resize_impath = kakao_ocr_resize(image_path)
    if resize_impath is not None:
        image_path = resize_impath
        print("원본 대신 리사이즈된 이미지를 사용합니다.")

    output = kakao_ocr(image_path, appkey).json()
    print("[OCR] output:\n{}\n".format(json.dumps(output, sort_keys=True,ensure_ascii=False, indent=2)))


if __name__ == "__main__":
    main()
  

다른 부분은 카카오 api 코드를 그대로 사용한 것이고 바꾼 부분은 main 쪽이다.

def main():
    if len(sys.argv) != 3:
        print("Please run with args: $ python example.py /path/to/image appkey")
    image_path, appkey = '이미지 경로', '발급받은 APP키'
    
    # 이미지 크기 조절
    white = [255,255,255]
    img=cv2.imread(image_path)
    constant= cv2.copyMakeBorder(img,200,100,100,100,cv2.BORDER_CONSTANT,value=white)
   
    #생성한 jpg경로에 저장하고 경로 초기화
    image_path='/content/drive/MyDrive/ts/swpg.jpg'
    cv2.imwrite(image_path, constant)
    cv2_imshow(constant)
    time.sleep(2)
    
    resize_impath = kakao_ocr_resize(image_path)
    if resize_impath is not None:
        image_path = resize_impath
        print("원본 대신 리사이즈된 이미지를 사용합니다.")

    output = kakao_ocr(image_path, appkey).json()
    print("[OCR] output:\n{}\n".format(json.dumps(output, sort_keys=True,ensure_ascii=False, indent=2)))

그냥 이미지를 넣으면 이 멍청이가 읽지를 못해서 주어진 이미지에 경계를 임의로 추가해주었다.

원래는 흑백처리를 하고 넣어서 흰색이 티가 별로 나지 않았는데 , 그리고 티가 나면 새로운 경계로 인식할까봐 걱정했는데 input이미지가

이런데도

인식을 잘했다.

그냥 이미지가 너무 작으면 안되나보다.

그리고 json파일을 읽어올 때

이렇게 한글을 못하는 경우가 있어서 아래와 같이 수정했다.

# 기본코드에 ensure_ascii=False 를 추가
print("[OCR] output:\n{}\n".format(json.dumps(output, sort_keys=True,ensure_ascii=False, indent=2)))

 

찾아보니 api를 다들 html이나 이미 존재하는 서비스에 도입한 것 같던데, 우린 아직 로컬/코랩에서 사용해야해서 경로를 직접지정하고 아웃풋을 json파일이 아닌 프린트로 받았다.

 

카카오 사랑해 날 데려가~

반응형