GABRIELSZK commited on
Commit
07c89f0
·
verified ·
1 Parent(s): 9afb7d7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -15
app.py CHANGED
@@ -7,7 +7,7 @@ import pytesseract
7
  from PIL import Image, ImageEnhance, ImageFilter
8
  import io
9
 
10
- # 🎯 Faixas de referência
11
  faixas = {
12
  "LEUCO": (4000, 11000),
13
  "B": (0, 1), "SS": (45, 59), "EOS": (1, 6), "LINF": (30, 50), "MONO": (1, 8),
@@ -41,19 +41,34 @@ def classificar(nome, valor):
41
  except:
42
  return valor
43
 
 
44
  def melhorar_imagem(img: Image.Image) -> Image.Image:
45
  img = img.convert("L")
46
  img = ImageEnhance.Contrast(img).enhance(2)
47
  return img.filter(ImageFilter.SHARPEN)
48
 
 
49
  def extrair_texto_pdf(pdf_input):
50
- # ... (mesma função de antes)
51
- # retorna texto nativo e OCR como uma única linha, com espaços
52
- ...
 
 
 
53
 
54
- # Padrões de extração — agora com word‐boundaries e unidades obrigatórias
 
 
 
 
 
 
 
 
 
 
 
55
  exames = {
56
- # Hemograma
57
  "LEUCO": r"\bleuc[óo]citos\b.*?([\d.,]+)\s*/u?l",
58
  "B": r"\bbastonetes\b.*?([\d.,]+)\s?%",
59
  "SS": r"\bsegmentados\b.*?([\d.,]+)\s?%",
@@ -63,7 +78,6 @@ exames = {
63
  "HB": r"\bhemoglobina\b.*?([\d.,]+)\s?g/dl",
64
  "HT": r"\bhemat[óo]crito\b.*?([\d.,]+)\s?%",
65
  "PLT": r"\bplaquetas\b.*?([\d.,]+)\s*/u?l",
66
- # Bioquímica
67
  "AMIL": r"\bamilase\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
68
  "BT": r"\bbilirrubina total\b.*?([\d.,]+)\s?mg/dl",
69
  "BD": r"\bbilirrubina direta\b.*?([\d.,]+)\s?mg/dl",
@@ -77,18 +91,15 @@ exames = {
77
  "GLI": r"\bglicose\b(?! qualitativa).*?resultado[:\s]*([\d.,]+)\s?mg/dl",
78
  "LIP": r"\blipase\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
79
  "MG++": r"\bmagn[eé]sio\b.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
80
- # Coagulação
81
  "TAP": r"\btempo de protrombina\b.*?resultado[:\s]*([\d.,]+)",
82
  "INR": r"\binr\b.*?([\d.,]+)",
83
  "TTP": r"\bttpa\b.*?resultado[:\s]*([\d.,]+)",
84
  "DIMERO D": r"\bd[ií]mero d\b.*?resultado[:\s]*([\d.,]+)",
85
- # Inflamatório e Cardíacos
86
  "PCR": r"\bpcr\b.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
87
  "CKMB": r"\bck[- ]?mb\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
88
  "CPK": r"\bcpk\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
89
- "TROPONINA": r"troponina(?! qualitativa).*?resultado[:\s]*([><\d.,]+)(?=\s*ng\/?m[lL])",
90
  "TROPONINA QUAL": r"troponina qualitativa.*?resultado[:\s]*(positivo|negativo)",
91
- # EAS completo (Urina)
92
  "PROTEINA UR": r"\bprote[ií]na\b.*?\b(ausente|positivo|negativo)",
93
  "GLI UR": r"\bglicose\b.*?\b(ausente|positivo|negativo)",
94
  "CETONAS UR": r"\bcorpos cet[oô]nicos\b.*?\b(ausente|positivo|negativo)",
@@ -100,13 +111,13 @@ exames = {
100
  "BACTERIAS UR": r"\bbact[ée]rias?\b.*?\b(raras|ausentes|positivas|negativas)"
101
  }
102
 
 
103
  ordem = [
104
  "LEUCO","B","SS","EOS","LINF","MONO",
105
  "HB","HT","PLT","AMIL","BT","BD","BI",
106
  "CR","UREIA","FAL","GGT","TGO","TGP","GLI","LIP","MG++",
107
  "PCR","CKMB","CPK","TROPONINA","TROPONINA QUAL",
108
  "TAP","INR","TTP","DIMERO D",
109
- # EAS
110
  "PROTEINA UR","GLI UR","CETONAS UR","SANGUE UR","LEUC ESTERASE","NITRITO UR","LEUCO EAS","HEMA EAS","BACTERIAS UR"
111
  ]
112
 
@@ -132,14 +143,15 @@ def extrair_exames_formatado(pdf_file):
132
  line_main = ' / '.join(main_fields)
133
  final = '\n'.join([l for l in (line_eas, line_main) if l])
134
 
135
- # Gera CSV
136
  df = pd.DataFrame([[k, resultados[k]] for k in resultados], columns=["Exame", "Valor"])
137
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
138
  df.to_csv(tmp.name, index=False)
139
  return final, tmp.name
140
 
141
- # UI Gradio
142
- with gr.Blocks() as demo:
 
143
  gr.Markdown("## 🧪 Extrator Avançado com OCR + EAS + Troponina (Quant. e Qual.)")
144
  pdf_input = gr.File(file_types=[".pdf"], label="📄 PDF de exames")
145
  btn = gr.Button("🔍 Extrair")
 
7
  from PIL import Image, ImageEnhance, ImageFilter
8
  import io
9
 
10
+ # 🎯 Faixas de referência (valores de referência mínimos e máximos)
11
  faixas = {
12
  "LEUCO": (4000, 11000),
13
  "B": (0, 1), "SS": (45, 59), "EOS": (1, 6), "LINF": (30, 50), "MONO": (1, 8),
 
41
  except:
42
  return valor
43
 
44
+ # Ajustes para melhorar OCR
45
  def melhorar_imagem(img: Image.Image) -> Image.Image:
46
  img = img.convert("L")
47
  img = ImageEnhance.Contrast(img).enhance(2)
48
  return img.filter(ImageFilter.SHARPEN)
49
 
50
+ # Extrai texto nativo + OCR do PDF
51
  def extrair_texto_pdf(pdf_input):
52
+ if isinstance(pdf_input, dict):
53
+ pdf_path = pdf_input.get("name") or pdf_input.get("file_path")
54
+ elif hasattr(pdf_input, "name") and isinstance(pdf_input.name, str):
55
+ pdf_path = pdf_input.name
56
+ else:
57
+ pdf_path = str(pdf_input)
58
 
59
+ texto_nativo, ocr_imgs = [], []
60
+ with fitz.open(pdf_path) as doc:
61
+ for page in doc:
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(melhorar_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
+
70
+ # Padrões de extração com word boundaries e unidades obrigatórias
71
  exames = {
 
72
  "LEUCO": r"\bleuc[óo]citos\b.*?([\d.,]+)\s*/u?l",
73
  "B": r"\bbastonetes\b.*?([\d.,]+)\s?%",
74
  "SS": r"\bsegmentados\b.*?([\d.,]+)\s?%",
 
78
  "HB": r"\bhemoglobina\b.*?([\d.,]+)\s?g/dl",
79
  "HT": r"\bhemat[óo]crito\b.*?([\d.,]+)\s?%",
80
  "PLT": r"\bplaquetas\b.*?([\d.,]+)\s*/u?l",
 
81
  "AMIL": r"\bamilase\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
82
  "BT": r"\bbilirrubina total\b.*?([\d.,]+)\s?mg/dl",
83
  "BD": r"\bbilirrubina direta\b.*?([\d.,]+)\s?mg/dl",
 
91
  "GLI": r"\bglicose\b(?! qualitativa).*?resultado[:\s]*([\d.,]+)\s?mg/dl",
92
  "LIP": r"\blipase\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
93
  "MG++": r"\bmagn[eé]sio\b.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
 
94
  "TAP": r"\btempo de protrombina\b.*?resultado[:\s]*([\d.,]+)",
95
  "INR": r"\binr\b.*?([\d.,]+)",
96
  "TTP": r"\bttpa\b.*?resultado[:\s]*([\d.,]+)",
97
  "DIMERO D": r"\bd[ií]mero d\b.*?resultado[:\s]*([\d.,]+)",
 
98
  "PCR": r"\bpcr\b.*?resultado[:\s]*([\d.,]+)\s?mg/dl",
99
  "CKMB": r"\bck[- ]?mb\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
100
  "CPK": r"\bcpk\b.*?resultado[:\s]*([\d.,]+)\s?u/l",
101
+ "TROPONINA": r"troponina(?! qualitativa).*?resultado[:\s]*([><\d.,]+)(?=\s*ng\/m[lL])",
102
  "TROPONINA QUAL": r"troponina qualitativa.*?resultado[:\s]*(positivo|negativo)",
 
103
  "PROTEINA UR": r"\bprote[ií]na\b.*?\b(ausente|positivo|negativo)",
104
  "GLI UR": r"\bglicose\b.*?\b(ausente|positivo|negativo)",
105
  "CETONAS UR": r"\bcorpos cet[oô]nicos\b.*?\b(ausente|positivo|negativo)",
 
111
  "BACTERIAS UR": r"\bbact[ée]rias?\b.*?\b(raras|ausentes|positivas|negativas)"
112
  }
113
 
114
+ # Ordem de exibição
115
  ordem = [
116
  "LEUCO","B","SS","EOS","LINF","MONO",
117
  "HB","HT","PLT","AMIL","BT","BD","BI",
118
  "CR","UREIA","FAL","GGT","TGO","TGP","GLI","LIP","MG++",
119
  "PCR","CKMB","CPK","TROPONINA","TROPONINA QUAL",
120
  "TAP","INR","TTP","DIMERO D",
 
121
  "PROTEINA UR","GLI UR","CETONAS UR","SANGUE UR","LEUC ESTERASE","NITRITO UR","LEUCO EAS","HEMA EAS","BACTERIAS UR"
122
  ]
123
 
 
143
  line_main = ' / '.join(main_fields)
144
  final = '\n'.join([l for l in (line_eas, line_main) if l])
145
 
146
+ # Gera CSV
147
  df = pd.DataFrame([[k, resultados[k]] for k in resultados], columns=["Exame", "Valor"])
148
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
149
  df.to_csv(tmp.name, index=False)
150
  return final, tmp.name
151
 
152
+ # Interface Gradio
153
+ demo = gr.Blocks()
154
+ with demo:
155
  gr.Markdown("## 🧪 Extrator Avançado com OCR + EAS + Troponina (Quant. e Qual.)")
156
  pdf_input = gr.File(file_types=[".pdf"], label="📄 PDF de exames")
157
  btn = gr.Button("🔍 Extrair")