| 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() |