|
import gradio as gr |
|
from transformers import TrOCRProcessor, VisionEncoderDecoderModel |
|
import torch |
|
from PIL import Image |
|
import numpy as np |
|
import cv2 |
|
|
|
|
|
processor = TrOCRProcessor.from_pretrained('microsoft/trocr-base-handwritten') |
|
model = VisionEncoderDecoderModel.from_pretrained('microsoft/trocr-base-handwritten') |
|
|
|
|
|
answer_key = { |
|
"1": {"answer": "๋ฏผ์ฃผ์ฃผ์", "explanation": "๋ฏผ์ฃผ์ฃผ์๋ ๊ตญ๋ฏผ์ด ์ฃผ์ธ์ด ๋์ด ๋๋ผ์ ์ค์ํ ์ผ์ ๊ฒฐ์ ํ๋ ์ ๋์
๋๋ค."}, |
|
"2": {"answer": "์ผ๊ถ๋ถ๋ฆฝ", "explanation": "์ผ๊ถ๋ถ๋ฆฝ์ ์
๋ฒ๋ถ, ํ์ ๋ถ, ์ฌ๋ฒ๋ถ๋ก ๊ถ๋ ฅ์ ๋๋์ด ์๋ก ๊ฒฌ์ ์ ๊ท ํ์ ์ด๋ฃจ๊ฒ ํ๋ ์ ๋์
๋๋ค."}, |
|
"3": {"answer": "์ง๋ฐฉ์์น์ ๋", "explanation": "์ง๋ฐฉ์์น์ ๋๋ ์ง์ญ์ ์ผ์ ๊ทธ ์ง์ญ ์ฃผ๋ฏผ๋ค์ด ์ง์ ๊ฒฐ์ ํ๊ณ ์ฒ๋ฆฌํ๋ ์ ๋์
๋๋ค."}, |
|
"4": {"answer": "ํ๋ฒ", "explanation": "ํ๋ฒ์ ๊ตญ๊ฐ์ ์ต๊ณ ๋ฒ์ผ๋ก, ๊ตญ๋ฏผ์ ๊ธฐ๋ณธ๊ถ๊ณผ ์ ๋ถ ์กฐ์ง์ ๋ํ ๊ธฐ๋ณธ ์์น์ ๋ด๊ณ ์์ต๋๋ค."}, |
|
"5": {"answer": "๊ตญํ", "explanation": "๊ตญํ๋ ๋ฒ๋ฅ ์ ๋ง๋ค๊ณ ์ ๋ถ๋ฅผ ๊ฐ์ํ๋ ์
๋ฒ๋ถ์ ์ญํ ์ ๋ด๋นํฉ๋๋ค."}, |
|
|
|
} |
|
|
|
def segment_answers(image): |
|
"""์ํ์ง์์ ๋ต์ ์์ญ์ ๋ถํ ํ๋ ํจ์""" |
|
if isinstance(image, np.ndarray): |
|
pil_image = Image.fromarray(image) |
|
else: |
|
return None |
|
|
|
|
|
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) |
|
|
|
|
|
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) |
|
|
|
|
|
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
|
|
|
|
|
answer_regions = [] |
|
for contour in contours: |
|
x, y, w, h = cv2.boundingRect(contour) |
|
if w > 50 and h > 20: |
|
region = image[y:y+h, x:x+w] |
|
answer_regions.append({ |
|
'image': region, |
|
'position': (y, x) |
|
}) |
|
|
|
|
|
answer_regions.sort(key=lambda x: x['position'][0]) |
|
|
|
return [region['image'] for region in answer_regions] |
|
|
|
def recognize_text(image): |
|
"""์๊ธ์จ ์ธ์ ํจ์""" |
|
if isinstance(image, np.ndarray): |
|
image = Image.fromarray(image) |
|
|
|
pixel_values = processor(image, return_tensors="pt").pixel_values |
|
|
|
with torch.no_grad(): |
|
generated_ids = model.generate(pixel_values) |
|
|
|
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0] |
|
return generated_text |
|
|
|
def grade_answer(question_number, student_answer): |
|
"""๋ต์ ์ฑ์ ํจ์""" |
|
question_number = str(question_number) |
|
if question_number not in answer_key: |
|
return None |
|
|
|
correct_answer = answer_key[question_number]["answer"] |
|
explanation = answer_key[question_number]["explanation"] |
|
|
|
|
|
is_correct = student_answer.replace(" ", "").lower() == correct_answer.replace(" ", "").lower() |
|
|
|
return { |
|
"๋ฌธ์ ๋ฒํธ": question_number, |
|
"ํ์๋ต์": student_answer, |
|
"์ ๋ต์ฌ๋ถ": "O" if is_correct else "X", |
|
"์ ๋ต": correct_answer, |
|
"ํด์ค": explanation |
|
} |
|
|
|
def process_full_exam(image): |
|
"""์ ์ฒด ์ํ์ง ์ฒ๋ฆฌ ํจ์""" |
|
if image is None or not isinstance(image, np.ndarray): |
|
return "์ํ์ง ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํด์ฃผ์ธ์." |
|
|
|
try: |
|
|
|
answer_regions = segment_answers(image) |
|
if not answer_regions: |
|
return "๋ต์ ์์ญ์ ์ฐพ์ ์ ์์ต๋๋ค. ์ด๋ฏธ์ง๋ฅผ ํ์ธํด์ฃผ์ธ์." |
|
|
|
|
|
results = [] |
|
total_correct = 0 |
|
|
|
|
|
for idx, region in enumerate(answer_regions, 1): |
|
if idx > len(answer_key): |
|
break |
|
|
|
|
|
recognized_text = recognize_text(region) |
|
|
|
|
|
result = grade_answer(idx, recognized_text) |
|
if result: |
|
results.append(result) |
|
if result["์ ๋ต์ฌ๋ถ"] == "O": |
|
total_correct += 1 |
|
|
|
|
|
score = (total_correct / len(results)) * 100 |
|
output = f"์ด์ : {score:.1f}์ (20๋ฌธ์ ์ค {total_correct}๊ฐ ์ ๋ต)\n\n" |
|
output += "=== ์์ธ ์ฑ์ ๊ฒฐ๊ณผ ===\n\n" |
|
|
|
for result in results: |
|
output += f""" |
|
[{result['๋ฌธ์ ๋ฒํธ']}๋ฒ] {'โ' if result['์ ๋ต์ฌ๋ถ']=='O' else 'โ'} |
|
ํ์๋ต์: {result['ํ์๋ต์']} |
|
์ ๋ต: {result['์ ๋ต']} |
|
ํด์ค: {result['ํด์ค']} |
|
""" |
|
|
|
return output |
|
|
|
except Exception as e: |
|
return f"์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}" |
|
|
|
|
|
iface = gr.Interface( |
|
fn=process_full_exam, |
|
inputs=gr.Image(label="์ํ์ง ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ์ธ์", type="numpy"), |
|
outputs=gr.Textbox(label="์ฑ์ ๊ฒฐ๊ณผ"), |
|
title="์ด๋ฑํ๊ต ์ฌํ ์ํ์ง ์ฑ์ ํ๋ก๊ทธ๋จ", |
|
description=""" |
|
์ ์ฒด ์ํ์ง๋ฅผ ํ ๋ฒ์ ์ฑ์ ํ๋ ํ๋ก๊ทธ๋จ์
๋๋ค. |
|
์ํ์ง์ ๋ต์์ด ์ ๋ณด์ด๋๋ก ๊นจ๋ํ๊ฒ ์ค์บํ๊ฑฐ๋ ์ดฌ์ํด์ฃผ์ธ์. |
|
""", |
|
examples=[], |
|
) |
|
|
|
if __name__ == "__main__": |
|
iface.launch() |