GABRIELSZK commited on
Commit
8171eaa
·
verified ·
1 Parent(s): ad434b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -50
app.py CHANGED
@@ -28,20 +28,15 @@ faixas = {
28
  "TROPONINA": (0, 0.5)
29
  }
30
 
31
- # Chaves relativas à seção EAS
32
- EAS_KEYS = [
33
- "PROTEINA UR","GLI UR","CETONAS UR","SANGUE UR",
34
- "LEUC ESTERASE","NITRITO UR","LEUCO EAS","HEMA EAS","BACTERIAS UR"
35
- ]
36
-
37
  def classificar(nome, valor):
38
- """Anexa ↓/↑ se fora da faixa."""
39
  try:
40
  v = float(valor.replace(">", "").replace("<", "").strip())
41
- lo, hi = faixas.get(nome, (None, None))
42
- if lo is not None:
43
- if v < lo: return f"{valor} ↓"
44
- if v > hi: return f"{valor} "
 
 
45
  return valor
46
  except:
47
  return valor
@@ -67,8 +62,8 @@ def extrair_texto_pdf(pdf_input):
67
  texto_nativo.append(page.get_text())
68
  pix = page.get_pixmap(dpi=300)
69
  img = Image.open(io.BytesIO(pix.tobytes("png")))
70
- ocr_imgs.append(melhorar_imagem(img))
71
- tn = re.sub(r"\s+", " ", " ".join(texto_nativo))
72
  tocr = re.sub(r"\s+", " ", " ".join(pytesseract.image_to_string(im) for im in ocr_imgs))
73
  return tn, tocr
74
 
@@ -76,54 +71,100 @@ def extrair_texto_pdf(pdf_input):
76
  exames = {
77
  # Hemograma
78
  "LEUCO": r"leuc[óo]citos.*?([\d.,]+)\s*/u?l",
79
- "B": r"bas[óo]filos.*?([\d.,]+)\s?%",
80
- "SS": r"segmentados.*?([\d.,]+)\s?%",
81
- "EOS": r"eosin[óo]filos.*?([\d.,]+)\s?%",
82
  "LINF": r"linf[oó]citos.*?([\d.,]+)\s?%",
83
  "MONO": r"mon[óo]citos.*?([\d.,]+)\s?%",
84
- "HB": r"hemoglobina.*?([\d.,]+)\s?g/dl",
85
- "HT": r"hemat[óo]crito.*?([\d.,]+)\s?%",
86
- "PLT": r"plaquetas.*?([\d.,]+).*?/u?l",
87
  # Bioquímica
88
  "AMIL": r"amilase.*?resultado[:\s]*([\d.,]+)\s?u/l",
89
- "BT": r"bilirrubina total.*?([\d.,]+)\s?mg/dl",
90
- "BD": r"bilirrubina direta.*?([\d.,]+)\s?mg/dl",
91
- "BI": r"bilirrubina indireta.*?([\d.,]+)\s?mg/dl",
92
- "CR": r"creatinina.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
93
- "UREIA": r"ureia.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
94
- "FAL": r"fosfatase alcalina.*?resultado[:\s]*([\d.,]+)\s?u/l",
95
- "GGT": r"ggt.*?resultado[:\s]*([\d.,]+)\s?u/l",
96
- "TGO": r"tgo.*?resultado[:\s]*([\d.,]+)\s?u/l",
97
- "TGP": r"tgp.*?resultado[:\s]*([\d.,]+)\s?u/l",
98
- "GLI": r"glicose(?! qualitativa).*?resultado[:\s]*([\d.,]+)\s?mg/dl",
99
- "LIP": r"lipase.*?resultado[:\s]*([\d.,]+)\s?u/l",
100
  "MG++": r"magn[eé]sio.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
101
  # Coagulação
102
- "TAP": r"tempo de protrombina.*?resultado[:\s]*([\d.,]+)",
103
- "INR": r"inr.*?([\d.,]+)",
104
- "TTP": r"ttpa.*?resultado[:\s]*([\d.,]+)",
105
  "DIMERO D": r"d[ií]mero d.*?resultado[:\s]*([\d.,]+)",
106
  # Inflamatório e Cardíacos
107
- "PCR": r"pcr.*?resultado[:\s]*([\d.,]+)",
108
- "CKMB": r"ck[- ]?mb.*?resultado[:\s]*([\d.,]+)",
109
- "CPK": r"cpk.*?resultado[:\s]*([\d.,]+)",
110
- "TROPONINA": r"troponina(?! qualitativa).*?resultado[:\s]*([>\d.,]+)",
111
  "TROPONINA QUAL": r"troponina qualitativa.*?resultado[:\s]*(positivo|negativo)",
112
- # EAS completo (Urina) apenas quando válido
113
- "PROTEINA UR": r"prote[ií]na\s*(ausente|positivo|negativo)",
114
- "GLI UR": r"glicose\s*(ausente|positivo|negativo)",
115
- "CETONAS UR": r"corpos cet[oô]nicos.*?(ausente|positivo|negativo)",
116
- "SANGUE UR": r"sangue\s*[:\-]?\s*(ausente|positivo|negativo)",
117
- "LEUC ESTERASE": r"leuc[óo]cito esterase\s*[:\-]?\s*(ausente|positivo|negativo)",
118
- "NITRITO UR": r"nitrito\s*(ausente|positivo|negativo)",
119
- "LEUCO EAS": r"leuc[óo]citos?\s*(\d+[-\/]\d+)",
120
- "HEMA EAS": r"hem[áa]cias?\s*(\d+[-\/]\d+)",
121
- "BACTERIAS UR": r"bact[ée]rias?\s*(ausente|raras|frequentes|positivas)"
122
  }
123
 
124
- # Ordem para exibição
125
  ordem = [
126
  "LEUCO","B","SS","EOS","LINF","MONO",
127
  "HB","HT","PLT","AMIL","BT","BD","BI",
128
- "CR","UREIA","
129
- ]}]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  "TROPONINA": (0, 0.5)
29
  }
30
 
 
 
 
 
 
 
31
  def classificar(nome, valor):
 
32
  try:
33
  v = float(valor.replace(">", "").replace("<", "").strip())
34
+ if nome in faixas:
35
+ lo, hi = faixas[nome]
36
+ if v < lo:
37
+ return f"{valor} "
38
+ if v > hi:
39
+ return f"{valor} ↑"
40
  return valor
41
  except:
42
  return valor
 
62
  texto_nativo.append(page.get_text())
63
  pix = page.get_pixmap(dpi=300)
64
  img = Image.open(io.BytesIO(pix.tobytes("png")))
65
+ ocr_imgs.append(melhor_imagem(img))
66
+ tn = re.sub(r"\s+", " ", "".join(texto_nativo))
67
  tocr = re.sub(r"\s+", " ", " ".join(pytesseract.image_to_string(im) for im in ocr_imgs))
68
  return tn, tocr
69
 
 
71
  exames = {
72
  # Hemograma
73
  "LEUCO": r"leuc[óo]citos.*?([\d.,]+)\s*/u?l",
74
+ "B": r"bas[óo]filos.*?([\d.,]+)\s?%",
75
+ "SS": r"segmentados.*?([\d.,]+)\s?%",
76
+ "EOS": r"eosin[óo]filos.*?([\d.,]+)\s?%",
77
  "LINF": r"linf[oó]citos.*?([\d.,]+)\s?%",
78
  "MONO": r"mon[óo]citos.*?([\d.,]+)\s?%",
79
+ "HB": r"hemoglobina.*?([\d.,]+)\s?g/dl",
80
+ "HT": r"hemat[óo]crito.*?([\d.,]+)\s?%",
81
+ "PLT": r"plaquetas.*?([\d.,]+).*?/u?l",
82
  # Bioquímica
83
  "AMIL": r"amilase.*?resultado[:\s]*([\d.,]+)\s?u/l",
84
+ "BT": r"bilirrubina total.*?([\d.,]+)\s?mg/dl",
85
+ "BD": r"bilirrubina direta.*?([\d.,]+)\s?mg/dl",
86
+ "BI": r"bilirrubina indireta.*?([\d.,]+)\s?mg/dl",
87
+ "CR": r"creatinina.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
88
+ "UREIA":r"ureia.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
89
+ "FAL": r"fosfatase alcalina.*?resultado[:\s]*([\d.,]+)\s?u/l",
90
+ "GGT": r"ggt.*?resultado[:\s]*([\d.,]+)\s?u/l",
91
+ "TGO": r"tgo.*?resultado[:\s]*([\d.,]+)\s?u/l",
92
+ "TGP": r"tgp.*?resultado[:\s]*([\d.,]+)\s?u/l",
93
+ "GLI": r"glicose(?! qualitativa).*?resultado[:\s]*([\d.,]+)\s?mg/dl",
94
+ "LIP": r"lipase.*?resultado[:\s]*([\d.,]+)\s?u/l",
95
  "MG++": r"magn[eé]sio.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
96
  # Coagulação
97
+ "TAP": r"tempo de protrombina.*?resultado[:\s]*([\d.,]+)",
98
+ "INR": r"inr.*?([\d.,]+)",
99
+ "TTP": r"ttpa.*?resultado[:\s]*([\d.,]+)",
100
  "DIMERO D": r"d[ií]mero d.*?resultado[:\s]*([\d.,]+)",
101
  # Inflamatório e Cardíacos
102
+ "PCR": r"pcr.*?resultado[:\s]*([\d.,]+)",
103
+ "CKMB": r"ck[- ]?mb.*?resultado[:\s]*([\d.,]+)",
104
+ "CPK": r"cpk.*?resultado[:\s]*([\d.,]+)",
105
+ "TROPONINA": r"troponina(?! qualitativa).*?resultado[:\s]*([>\d.,]+)",
106
  "TROPONINA QUAL": r"troponina qualitativa.*?resultado[:\s]*(positivo|negativo)",
107
+ # EAS completo (Urina)
108
+ "PROTEINA UR": r"prote[ií]na\s*(ausente|positivo|negativo)",
109
+ "GLI UR": r"glicose\s*(ausente|positivo|negativo)",
110
+ "CETONAS UR": r"corpos cet[oô]nicos.*?(ausente|positivo|negativo)",
111
+ "SANGUE UR": r"sangue\s*(ausente|positivo|negativo)",
112
+ "LEUC ESTERASE": r"leuc[óo]citos? esterase\s*[:\-]?\s*(ausente|positivo|negativo)",
113
+ "NITRITO UR": r"nitrito\s*(ausente|positivo|negativo)",
114
+ "LEUCO EAS": r"leuc[óo]citos?\s*([\d]+[-\/–][\d]+)",
115
+ "HEMA EAS": r"hem[áa]cias?\s*([\d]+[-\/–][\d]+)",
116
+ "BACTERIAS UR": r"bact[ée]rias?\s*(raras|ausentes|positivas|negativas)"
117
  }
118
 
 
119
  ordem = [
120
  "LEUCO","B","SS","EOS","LINF","MONO",
121
  "HB","HT","PLT","AMIL","BT","BD","BI",
122
+ "CR","UREIA","FAL","GGT","TGO","TGP","GLI","LIP","MG++",
123
+ "PCR","CKMB","CPK","TROPONINA","TROPONINA QUAL",
124
+ "TAP","INR","TTP","DIMERO D",
125
+ # EAS
126
+ "PROTEINA UR","GLI UR","CETONAS UR","SANGUE UR","LEUC ESTERASE","NITRITO UR","LEUCO EAS","HEMA EAS","BACTERIAS UR"
127
+ ]
128
+
129
+ # Montagem do texto formatado
130
+ def extrair_exames_formatado(pdf_file):
131
+ if not pdf_file:
132
+ return "Nenhum arquivo enviado.", None
133
+ tn, tocr = extrair_texto_pdf(pdf_file)
134
+ texto = (tn + " " + tocr).lower()
135
+ resultados = {}
136
+ for nome, pat in exames.items():
137
+ m = re.search(pat, texto, re.IGNORECASE)
138
+ if not m:
139
+ continue
140
+ raw = m.group(1).strip().upper()
141
+ # se for valor qualitativo ou EAS, mantém texto
142
+ if "QUAL" in nome or nome.endswith("UR") or nome.endswith("EAS"):
143
+ resultados[nome] = raw
144
+ else:
145
+ resultados[nome] = classificar(nome, raw.replace(",", "."))
146
+
147
+ # Linhas EAS e principais
148
+ eas_fields = [f"{k}: {resultados[k]}" for k in ordem if k in resultados and (k.endswith("UR") or k.endswith("EAS"))]
149
+ main_fields = [f"{r}: {resultados[r]}" for r in ordem if r in resultados and not (r.endswith("UR") or r.endswith("EAS"))]
150
+ line_eas = f"🟤 EAS → {' / '.join(eas_fields)}" if eas_fields else ""
151
+ line_main = ' / '.join(main_fields)
152
+ final = '\n'.join([l for l in (line_eas, line_main) if l])
153
+
154
+ # CSV
155
+ df = pd.DataFrame([[k, resultados[k]] for k in resultados], columns=["Exame","Valor"])
156
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
157
+ df.to_csv(tmp.name, index=False)
158
+ return final, tmp.name
159
+
160
+ # Gradio UI
161
+ with gr.Blocks() as demo:
162
+ gr.Markdown("## 🧪 Extrator Avançado com OCR + EAS + Troponina (Quant. e Qual.)")
163
+ pdf_input = gr.File(file_types=[".pdf"], label="📄 PDF de exames")
164
+ btn = gr.Button("🔍 Extrair")
165
+ out_txt = gr.Textbox(lines=15, label="📋 Resultados")
166
+ dl = gr.File(label="📥 Baixar CSV")
167
+ btn.click(extrair_exames_formatado, inputs=pdf_input, outputs=[out_txt, dl])
168
+
169
+ if __name__ == "__main__":
170
+ demo.launch()