GABRIELSZK commited on
Commit
4a45397
·
verified ·
1 Parent(s): d094d4f

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +1 -136
  2. requirements.txt +4 -1
app.py CHANGED
@@ -1,136 +1 @@
1
- import fitz
2
- import re
3
- import gradio as gr
4
- import pandas as pd
5
- import tempfile
6
-
7
- # Faixas de referência básicas para classificação (valores em mg/dL, g/dL, etc.)
8
- faixas = {
9
- "HB": (12, 17),
10
- "HT": (36, 50),
11
- "GLI": (70, 99),
12
- "UREIA": (10, 50),
13
- "CR": (0.6, 1.3),
14
- "K+": (3.5, 5.5),
15
- "NA+": (135, 145),
16
- "TGO": (0, 40),
17
- "TGP": (0, 40),
18
- "ALB": (3.5, 5.0),
19
- "INR": (0.8, 1.2),
20
- "TAP": (10, 14),
21
- "TTP": (25, 35),
22
- "LAC": (0.5, 2.2),
23
- "PLT": (150000, 450000),
24
- "LEUCO": (4000, 11000)
25
- }
26
-
27
- def classificar(nome, valor):
28
- try:
29
- val = float(valor.replace("K", "000").replace(">", "").replace("<", "").strip())
30
- if nome in faixas:
31
- min_v, max_v = faixas[nome]
32
- if val < min_v:
33
- return f"{valor} ↓"
34
- elif val > max_v:
35
- return f"{valor} ↑"
36
- return valor
37
- except:
38
- return valor
39
-
40
- def extrair_exames_formatado(pdf_file):
41
- if pdf_file is None:
42
- return "Nenhum arquivo enviado.", None
43
-
44
- texto = ""
45
- with fitz.open(pdf_file.name) as doc:
46
- for page in doc:
47
- texto += page.get_text()
48
-
49
- texto = texto.replace('\n', ' ').replace('\r', ' ')
50
-
51
- def buscar(padrao, excluir_protocolo=True):
52
- matches = re.findall(padrao, texto, re.IGNORECASE)
53
- for match in matches:
54
- val = match.strip().replace(",", ".")
55
- if excluir_protocolo and len(val.replace(".", "").replace(">", "").replace("<", "")) > 5:
56
- continue # ignora IDs longos como 2500267046
57
- return val
58
- return None
59
-
60
- def k_format(v):
61
- try:
62
- n = float(v)
63
- return f"{round(n / 1000, 1)}K" if n >= 1000 else str(n)
64
- except:
65
- return v
66
-
67
- leuco = buscar(r"leuc[óo]citos[^:\d]{0,10}[:=]?\s*(\d{3,5})")
68
- bastonetes = buscar(r"bastonetes[^:\d]{0,10}[:=]?\s*(\d+)\s*%")
69
- segmentados = buscar(r"segmentados[^:\d]{0,10}[:=]?\s*(\d+)\s*%")
70
- leuco_str = ""
71
- if leuco:
72
- leuco_str = f"LEUCO {k_format(leuco)}"
73
- if bastonetes:
74
- leuco_str += f" + {bastonetes}% B"
75
- if segmentados:
76
- leuco_str += f" + {segmentados}% SS"
77
-
78
- campos = {
79
- "UREIA": r"ureia[^:\d]{0,10}[:=]?\s*([\d.,]+)",
80
- "CR": r"creatinina[^:\d]{0,10}[:=]?\s*([\d.,]+)",
81
- "K+": r"(?:pot[áa]ssio|k\+)[^:\d]{0,10}[:=]?\s*([\d.,]+)",
82
- "NA+": r"(?:s[óo]dio|na\+)[^:\d]{0,10}[:=]?\s*([\d.,]+)",
83
- "CL-": r"(?:cl[óo]ro)[^:\d]{0,10}[:=]?\s*([\d.,]+)",
84
- "CAI": r"ioniz[áa]vel[^:\d]{0,10}[:=]?\s*([\d.,]+)",
85
- "CA TOTAL": r"c[áa]lcio total[^:\d]{0,10}[:=]?\s*([\d.,]+)",
86
- "MG++": r"magn[ée]sio[^:\d]{0,10}[:=]?\s*([\d.,]+)",
87
- "FÓS": r"f[óo]sforo[^:\d]{0,10}[:=]?\s*([\d.,]+)",
88
- "GLI": r"glicose[^:\d]{0,10}[:=]?\s*([\d.,]+)",
89
- "HB": r"hemoglobina[^:\d]{0,10}[:=]?\s*([\d.,]+)",
90
- "HT": r"hemat[óo]crito[^:\d]{0,10}[:=]?\s*([\d.,]+)",
91
- "PLT": r"plaquetas[^:\d]{0,10}[:=]?\s*([\d.,]+)",
92
- "INR": r"INR[^:\d]{0,10}[:=]?\s*([\d.,]+)",
93
- "TAP": r"\bTP[^:\d]{0,10}[:=]?\s*([\d.,]+)\s*seg",
94
- "TTP": r"TTPA[^:\d]{0,10}[:=]?\s*([\d.,]+)\s*seg",
95
- "RELAÇÃO": r"relaç[aã]o.*?(?:paciente|a\/g)[^:\d]{0,10}[:=]?\s*([\d.,]+)",
96
- "LAC": r"lactato[^:\d]{0,10}[:=]?\s*([\d.,]+)",
97
- "TGO": r"\bTGO[^:\d]{0,10}[:=]?\s*([\d.,]+)",
98
- "TGP": r"\bTGP[^:\d]{0,10}[:=]?\s*([\d.,]+)",
99
- "ALB": r"albumina[^:\d]{0,10}[:=]?\s*([\d.,]+)",
100
- "PCR": r"PCR[^:\d]{0,10}[:=]?\s*([\d.,]+)",
101
- "CPK": r"creatinofosfoquinase.*?[:=]?\s*([\d.,]+)",
102
- "CKMB": r"CKMB(?:\s*massa)?[^:\d]{0,10}[:=]?\s*([\d.,]+)",
103
- "TROPO": r"troponina.*?[:=]?\s*([<>]?\s*[\d.,]+)",
104
- }
105
-
106
- resultados = []
107
- if leuco_str:
108
- resultados.append(("LEUCO", leuco_str))
109
-
110
- for rotulo, padrao in campos.items():
111
- val = buscar(padrao)
112
- if val:
113
- val = classificar(rotulo, val)
114
- resultados.append((rotulo, val))
115
- else:
116
- resultados.append((rotulo, "—"))
117
-
118
- df = pd.DataFrame(resultados, columns=["Exame", "Valor"])
119
- texto_final = "\n".join([f"{r[0]}: {r[1]}" for r in resultados])
120
-
121
- # Exportação CSV temporária
122
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
123
- df.to_csv(temp_file.name, index=False)
124
-
125
- return texto_final, temp_file.name
126
-
127
- with gr.Blocks() as demo:
128
- gr.Markdown("## 🧪 Extrator Inteligente de Exames Laboratoriais - PDF para Diagnóstico")
129
- pdf_file = gr.File(label="📄 PDF de exames", file_types=[".pdf"])
130
- extract_button = gr.Button("🔍 Extrair Exames")
131
- output_text = gr.Textbox(label="📋 Exames extraídos e classificados", lines=25)
132
- download_button = gr.File(label="📥 Baixar CSV")
133
-
134
- extract_button.click(fn=extrair_exames_formatado, inputs=pdf_file, outputs=[output_text, download_button])
135
-
136
- demo.launch()
 
1
+ <CÓDIGO FINAL COM OCR INSERIDO AQUI (reduzido para visualização)>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,2 +1,5 @@
1
  gradio>=5.26.0
2
- PyMuPDF
 
 
 
 
1
  gradio>=5.26.0
2
+ pymupdf
3
+ pytesseract
4
+ pillow
5
+ pandas