[ 졸업프로젝트 ] 카카오 vision API(OCR) 사용하기 feat.Colab
카카오 좋은 기업이네..
사용할 이미지
결과 화면
[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파일이 아닌 프린트로 받았다.
카카오 사랑해 날 데려가~