LLDDWW commited on
Commit
5f1a404
ยท
1 Parent(s): 4363637

Add MedCard app and requirements

Browse files
Files changed (2) hide show
  1. app.py +94 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py (HF Space)
2
+ }
3
+
4
+
5
+
6
+
7
+ def ocr_and_parse(img) -> Dict[str, Any]:
8
+ """Run OCR then parse fields with basic validation."""
9
+ # OCR output is a list of dicts with 'generated_text'
10
+ raw = ocr(img)[0]["generated_text"]
11
+ fields = parse_fields(raw)
12
+
13
+
14
+ # basic validation messages
15
+ warn = []
16
+ if not fields["drug_name"]:
17
+ warn.append("์•ฝ ์ด๋ฆ„ ์ธ์‹์ด ๋ถˆํ™•์‹คํ•ฉ๋‹ˆ๋‹ค.")
18
+ if not fields["times_per_day"]:
19
+ warn.append("1์ผ ํšŸ์ˆ˜๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค (์˜ˆ: 1์ผ 3ํšŒ).")
20
+
21
+
22
+ return {"raw_text": raw, "fields": fields, "warnings": warn}
23
+
24
+
25
+
26
+
27
+ def render_card(fields: Dict[str, Any]) -> Image.Image:
28
+ """Draw a simple schedule card (PNG) from parsed fields."""
29
+ W, H = 720, 400
30
+ img = Image.new("RGB", (W, H), "white")
31
+ d = ImageDraw.Draw(img)
32
+ title = "์˜ค๋Š˜ ๋ณต์šฉ ์ผ์ •"
33
+ d.rectangle((0, 0, W, 60), fill=(230, 240, 255))
34
+ d.text((24, 18), title, fill=(0, 0, 0))
35
+
36
+
37
+ y = 90
38
+ def line(label, value):
39
+ nonlocal y
40
+ d.text((24, y), f"{label}", fill=(60, 60, 60))
41
+ d.text((180, y), f": {value if value else '-'}", fill=(0, 0, 0))
42
+ y += 34
43
+
44
+
45
+ line("์•ฝ ์ด๋ฆ„", fields.get("drug_name"))
46
+ line("1ํšŒ ์šฉ๋Ÿ‰", fields.get("dose_per_intake"))
47
+ line("1์ผ ํšŸ์ˆ˜", fields.get("times_per_day"))
48
+ slots = ", ".join(fields.get("time_slots") or [])
49
+ line("์‹œ๊ฐ„๋Œ€", slots if slots else None)
50
+
51
+
52
+ d.text((24, H-60), "โ€ป ์˜๋ฃŒ์ง„ ์ฒ˜๋ฐฉ ์šฐ์„ , ๋ณธ ์•ฑ์€ ์•ˆ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.", fill=(120, 120, 120))
53
+ return img
54
+
55
+
56
+
57
+
58
+ def run_pipeline(image):
59
+ if image is None:
60
+ return "์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•˜์„ธ์š”.", None, None
61
+ out = ocr_and_parse(image)
62
+ card = render_card(out["fields"])
63
+ csv_row = to_csv_row(out)
64
+ return json.dumps(out, ensure_ascii=False, indent=2), card, csv_row
65
+
66
+
67
+
68
+
69
+ def to_csv_row(out: Dict[str, Any]) -> str:
70
+ f = out["fields"]
71
+ row = [
72
+ f.get("drug_name") or "",
73
+ f.get("dose_per_intake") or "",
74
+ str(f.get("times_per_day") or ""),
75
+ ";".join(f.get("time_slots") or []),
76
+ ]
77
+ return ",".join(row)
78
+
79
+
80
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
81
+ gr.Markdown("# MedCard-KR ยท ์•ฝ๋ด‰ํˆฌ OCR โ†’ ๋ณต์šฉ ์ผ์ • ์นด๋“œ")
82
+ with gr.Row():
83
+ with gr.Column():
84
+ img_in = gr.Image(type="pil", label="์•ฝ ๋ด‰ํˆฌ/๋ผ๋ฒจ ์‚ฌ์ง„")
85
+ btn = gr.Button("์ธ์‹ & ์นด๋“œ ์ƒ์„ฑ", variant="primary")
86
+ csv = gr.Textbox(label="CSV(์•ฝ๋ช…,1ํšŒ์šฉ๋Ÿ‰,1์ผํšŸ์ˆ˜,์‹œ๊ฐ„๋Œ€)")
87
+ with gr.Column():
88
+ json_out = gr.Code(label="์ธ์‹ ๊ฒฐ๊ณผ(JSON)")
89
+ card = gr.Image(type="pil", label="์ผ์ • ์นด๋“œ(๋ฏธ๋ฆฌ๋ณด๊ธฐ)")
90
+ btn.click(run_pipeline, inputs=img_in, outputs=[json_out, card, csv])
91
+
92
+
93
+ if __name__ == "__main__":
94
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ transformers
2
+ gradio
3
+ Pillow