Azure 에서 제공하는 Document Intelligence Studio 를 활용해서 지능형 문서 처리 솔루션을 만드는 실습을 해보았다.
일부는 한글이 지원되지만 다수의 모델은 영문 전용인 점 참고!
Prebuilt Models 를 살펴보면
- Invoices: 고객 및 공급업체 세부 정보 추출 (한글 지원)
- Health Insueance card: 보험 적용 세부 정보를 추출 (영문)
- Business Card: 명함 세부 정보 추출 (한글 지원)
등등, 사용처를 보면 어떤 기술인지 얼추 감이 온다.


상단의 OCR/Read 를 실습해본다.
OCR(Optical Character Recognition)은 광학 문자 인식을 뜻하며, 텍스트 이미지를 기계가 읽을 수 있는 텍스트로 변환하는 기술으로, 텍스트 인식이라고도 불리기도 한다.
요즘은 스마트폰 앨범에서도, 구글번역 앱에서도 다 지원되는 기능이라 익숙하다.


해당 API 를 가져와서 파이썬과 그라디오로 구현해보도록 한다.
import gradio as gr
import requests
import time
from PIL import Image, ImageDraw
import random
# Document Intelligence API를 호출하여 문서 분석 결과를 반환하는 함수
def request_document_intelligence(file_path):
endpoint = "https://fimtrus-document-intelligence.cognitiveservices.azure.com/documentintelligence/documentModels/prebuilt-read:analyze?_overload=analyzeDocument&api-version=2024-11-30"
headers = {
"Ocp-Apim-Subscription-Key": #비밀, # API 키 입력 필요
"Content-Type": "image/png" # 이미지 형식 지정
}
# 이미지 파일을 바이너리 형태로 읽어오기
with open(file_path, "rb") as image:
image_data = image.read()
# Azure Document Intelligence API 요청 보내기
response = requests.post(endpoint, headers=headers, data=image_data)
# API가 비동기적으로 결과를 반환하므로, 202 응답이 올 경우 진행 상태를 확인해야 함
if response.status_code == 202:
result_url = response.headers['Operation-Location'] # 결과를 가져올 URL
while(True):
# 결과 요청하여 상태 확인
result_response = requests.get(result_url, headers={
"Ocp-Apim-Subscription-Key": headers["Ocp-Apim-Subscription-Key"]
})
result_response_json = result_response.json()
result_status = result_response_json['status']
if result_status == "running":
print(result_status) # 진행 중 상태 출력
time.sleep(1) # 1초 대기 후 다시 확인
continue
else:
break # 완료되면 루프 종료
# 분석 성공 시 결과 반환
if result_status == "succeeded":
print(result_status)
print(result_response_json)
return result_response_json
else:
return None # 실패 시 None 반환
# 랜덤한 색상을 생성하는 함수
def random_color():
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
# 분석 결과를 받아 입력 이미지 위에 텍스트 영역을 시각적으로 표시하는 함수
def draw_image(file_path, result_response):
image = Image.open(file_path) # 입력 이미지 열기
draw = ImageDraw.Draw(image) # 이미지를 수정할 수 있도록 draw 객체 생성
block_list = result_response['analyzeResult']['paragraphs'] # 분석된 문단 목록 가져오기
for block in block_list:
line_color = random_color() # 문단별 랜덤 색상 지정
polygon_list = block['boundingRegions'][0]['polygon'] # 문단 영역의 다각형 좌표
points = [(polygon_list[i], polygon_list[i + 1]) for i in range(0, len(polygon_list), 2)] # 좌표를 튜플 형태로 변환
content = block['content'] # 문단의 텍스트 내용
# 텍스트 영역을 이미지 위에 그리기
draw.polygon(points, outline=line_color, width=2) # 다각형 테두리 그리기
draw.text((points[0][0], points[0][1] - 10), content, fill=line_color) # 텍스트 표시
return image # 수정된 이미지 반환
# Gradio UI 구성
with gr.Blocks() as demo:
# 버튼 클릭 시 실행될 함수
def click_send(file_path):
result_response = request_document_intelligence(file_path) # Document Intelligence API 호출
image = draw_image(file_path, result_response) # 이미지에 분석 결과 반영
return image # 수정된 이미지 반환
input_image = gr.Image(label="입력 이미지", type="filepath") # 입력 이미지 업로드
send_button = gr.Button("전송") # 분석 요청 버튼
output_image = gr.Image(label="출력 이미지", interactive=False, type="pil") # 분석 결과 표시
send_button.click(click_send, inputs=[input_image], outputs=[output_image]) # 버튼 클릭 이벤트 연결
demo.launch() # Gradio 인터페이스 실행
# 테스트용 코드 (실제 사용 시 주석 해제 후 파일 경로 입력하여 사용)
# result_response = request_document_intelligence(file)
# draw_image(file, result_response)
그라디오 화면은 이렇다

상단에 텍스트가 포함된 이미지 파일을 넣어주면, 출력 이미지에 텍스트로 인식한 부분에 폴리곤 박스를 그려준다.
