Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -5,221 +5,192 @@ from PIL import Image
|
|
5 |
import io
|
6 |
from collections import defaultdict
|
7 |
|
8 |
-
def
|
9 |
"""
|
10 |
-
|
11 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
# Converter para escala de cinza
|
13 |
-
gray = cv2.cvtColor(
|
14 |
|
15 |
# Aplicar blur para reduzir ruído
|
16 |
blur = cv2.GaussianBlur(gray, (7, 7), 0)
|
17 |
|
18 |
-
# Detectar
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
cv2.HOUGH_GRADIENT,
|
22 |
dp=1,
|
23 |
minDist=50,
|
24 |
param1=50,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
param2=30,
|
26 |
-
minRadius=
|
27 |
maxRadius=150
|
28 |
)
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
-
def
|
52 |
"""
|
53 |
-
|
54 |
"""
|
55 |
-
if
|
56 |
return {}
|
57 |
|
58 |
# Converter para escala de cinza
|
59 |
-
gray = cv2.cvtColor(
|
60 |
-
|
61 |
-
# Análises de textura
|
62 |
-
padroes = {
|
63 |
-
"congestao_inflamacao": False,
|
64 |
-
"deficiencia_hipofuncao": False,
|
65 |
-
"atrofia_degeneracao": False,
|
66 |
-
"irritacao_estresse": False
|
67 |
-
}
|
68 |
-
|
69 |
-
# Análise de variância local
|
70 |
-
kernel_size = 5
|
71 |
-
local_var = cv2.Laplacian(gray, cv2.CV_64F).var()
|
72 |
-
|
73 |
-
# Análise de intensidade média
|
74 |
-
mean_intensity = np.mean(gray)
|
75 |
-
|
76 |
-
# Análise de contraste
|
77 |
-
contrast = np.std(gray)
|
78 |
-
|
79 |
-
# Detecção de bordas
|
80 |
-
edges = cv2.Canny(gray, 100, 200)
|
81 |
-
edge_density = np.sum(edges) / (edges.shape[0] * edges.shape[1])
|
82 |
-
|
83 |
-
# Definir limiares para cada padrão
|
84 |
-
if local_var > 100:
|
85 |
-
padroes["congestao_inflamacao"] = True
|
86 |
|
87 |
-
|
88 |
-
|
|
|
89 |
|
90 |
-
|
91 |
-
|
|
|
|
|
92 |
|
93 |
-
|
94 |
-
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
def analisar_setores(roi, centro, raio):
|
99 |
-
"""
|
100 |
-
Analisa diferentes setores da íris
|
101 |
-
"""
|
102 |
-
if roi is None:
|
103 |
-
return {}
|
104 |
|
|
|
105 |
setores = {
|
106 |
-
"superior": (315, 45),
|
107 |
-
"direito": (45, 135),
|
108 |
-
"inferior": (135, 225),
|
109 |
-
"esquerdo": (225, 315)
|
110 |
}
|
111 |
|
112 |
-
resultados = {}
|
113 |
-
|
114 |
for setor, (ang_inicio, ang_fim) in setores.items():
|
115 |
-
# Criar máscara
|
116 |
-
|
117 |
-
cv2.ellipse(
|
118 |
-
(
|
119 |
-
(
|
120 |
-
0,
|
121 |
-
ang_inicio,
|
122 |
-
ang_fim,
|
123 |
-
255,
|
124 |
-1)
|
125 |
|
126 |
-
# Aplicar máscara
|
127 |
-
setor_roi = cv2.bitwise_and(
|
128 |
|
129 |
-
#
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
|
134 |
-
def
|
135 |
"""
|
136 |
-
|
137 |
"""
|
138 |
-
|
139 |
-
|
140 |
-
# Mapeamento de padrões para possíveis condições
|
141 |
-
mapa_condicoes = {
|
142 |
-
"congestao_inflamacao": [
|
143 |
-
"Processo inflamatório ativo",
|
144 |
-
"Possível condição autoimune",
|
145 |
-
"Inflamação crônica"
|
146 |
-
],
|
147 |
-
"deficiencia_hipofuncao": [
|
148 |
-
"Deficiência nutricional",
|
149 |
-
"Hipofunção glandular",
|
150 |
-
"Fadiga crônica"
|
151 |
-
],
|
152 |
-
"atrofia_degeneracao": [
|
153 |
-
"Desgaste tecidual",
|
154 |
-
"Processo degenerativo",
|
155 |
-
"Envelhecimento acelerado"
|
156 |
-
],
|
157 |
-
"irritacao_estresse": [
|
158 |
-
"Estresse crônico",
|
159 |
-
"Sobrecarga do sistema nervoso",
|
160 |
-
"Ansiedade"
|
161 |
-
]
|
162 |
-
}
|
163 |
|
164 |
-
|
165 |
-
|
166 |
-
if presente:
|
167 |
-
diagnostico.extend(mapa_condicoes[padrao])
|
168 |
|
169 |
-
#
|
170 |
-
|
171 |
-
for padrao, presente in padroes_setor.items():
|
172 |
-
if presente:
|
173 |
-
if setor == "superior":
|
174 |
-
diagnostico.append(f"Região cerebral: {mapa_condicoes[padrao][0]}")
|
175 |
-
elif setor == "direito":
|
176 |
-
diagnostico.append(f"Região hepática: {mapa_condicoes[padrao][0]}")
|
177 |
-
elif setor == "inferior":
|
178 |
-
diagnostico.append(f"Região digestiva: {mapa_condicoes[padrao][0]}")
|
179 |
-
elif setor == "esquerdo":
|
180 |
-
diagnostico.append(f"Região cardíaca: {mapa_condicoes[padrao][0]}")
|
181 |
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
Processa a imagem da íris e retorna análise
|
187 |
-
"""
|
188 |
-
# Converter imagem para formato OpenCV
|
189 |
-
img_array = np.array(imagem)
|
190 |
|
191 |
-
#
|
192 |
-
|
193 |
-
if roi is None:
|
194 |
-
return "Não foi possível detectar a íris na imagem."
|
195 |
|
196 |
-
#
|
197 |
-
|
|
|
198 |
|
199 |
-
|
200 |
-
|
|
|
|
|
|
|
|
|
201 |
|
202 |
-
|
203 |
-
diagnostico = gerar_diagnostico(padroes, setores)
|
204 |
-
|
205 |
-
# Gerar visualização
|
206 |
-
output_img = img_array.copy()
|
207 |
-
cv2.circle(output_img, (x, y), r, (0, 255, 0), 2)
|
208 |
-
|
209 |
-
# Desenhar setores
|
210 |
-
ang_step = 45
|
211 |
-
for ang in range(0, 360, ang_step):
|
212 |
-
end_x = int(x + r * np.cos(np.radians(ang)))
|
213 |
-
end_y = int(y + r * np.sin(np.radians(ang)))
|
214 |
-
cv2.line(output_img, (x, y), (end_x, end_y), (0, 255, 0), 1)
|
215 |
-
|
216 |
-
return output_img, "\n".join(diagnostico)
|
217 |
|
218 |
def criar_interface():
|
219 |
"""
|
220 |
-
Cria interface
|
221 |
"""
|
222 |
-
# Tema personalizado verde piscina
|
223 |
theme = gr.themes.Soft(
|
224 |
primary_hue="teal",
|
225 |
secondary_hue="green",
|
@@ -232,11 +203,62 @@ def criar_interface():
|
|
232 |
button_primary_background_fill_dark="#264653",
|
233 |
)
|
234 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
# Interface
|
236 |
-
with gr.Blocks(theme=theme, title="Análise Iridológica
|
237 |
gr.Markdown("""
|
238 |
# Sistema Avançado de Análise Iridológica
|
239 |
-
###
|
240 |
""")
|
241 |
|
242 |
with gr.Tabs():
|
@@ -246,17 +268,17 @@ def criar_interface():
|
|
246 |
with gr.Column():
|
247 |
input_image = gr.Image(
|
248 |
label="Imagem da Íris",
|
249 |
-
type="
|
250 |
)
|
251 |
with gr.Column():
|
252 |
output_image = gr.Image(
|
253 |
-
label="
|
254 |
)
|
255 |
|
256 |
analysis_btn = gr.Button("Analisar Íris", variant="primary")
|
257 |
output_text = gr.Textbox(
|
258 |
-
label="
|
259 |
-
lines=
|
260 |
)
|
261 |
|
262 |
analysis_btn.click(
|
@@ -265,56 +287,32 @@ def criar_interface():
|
|
265 |
outputs=[output_image, output_text]
|
266 |
)
|
267 |
|
268 |
-
# Aba de
|
269 |
-
with gr.Tab("Guia de
|
270 |
gr.Markdown("""
|
271 |
-
##
|
272 |
-
|
273 |
-
### Padrões Principais
|
274 |
-
- **Congestão/Inflamação**: Áreas escuras ou densas
|
275 |
-
- **Deficiência/Hipofunção**: Áreas claras ou vazias
|
276 |
-
- **Atrofia/Degeneração**: Lacunas ou descontinuidades
|
277 |
-
- **Irritação/Estresse**: Linhas radiais ou manchas
|
278 |
|
279 |
-
###
|
280 |
-
1. **
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
### Recomendações
|
286 |
-
- Faça a foto com boa iluminação
|
287 |
-
- Mantenha o olho bem aberto
|
288 |
-
- Evite reflexos na imagem
|
289 |
-
- Use câmera com boa resolução
|
290 |
-
""")
|
291 |
-
|
292 |
-
# Aba de Recomendações
|
293 |
-
with gr.Tab("Recomendações"):
|
294 |
-
gr.Markdown("""
|
295 |
-
## Recomendações Gerais
|
296 |
-
|
297 |
-
### Qualidade da Imagem
|
298 |
-
- Resolução mínima: 1280x720
|
299 |
-
- Iluminação uniforme
|
300 |
-
- Foco na íris
|
301 |
-
- Sem reflexos
|
302 |
-
|
303 |
-
### Preparação
|
304 |
-
1. **Ambiente**
|
305 |
-
- Bem iluminado
|
306 |
-
- Sem luz direta
|
307 |
-
- Fundo claro
|
308 |
|
309 |
2. **Posicionamento**
|
310 |
- Olho bem aberto
|
311 |
-
-
|
312 |
-
-
|
|
|
|
|
|
|
|
|
|
|
313 |
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
|
|
318 |
""")
|
319 |
|
320 |
return interface
|
|
|
5 |
import io
|
6 |
from collections import defaultdict
|
7 |
|
8 |
+
def melhorar_contraste(imagem):
|
9 |
"""
|
10 |
+
Aplica equalização de histograma adaptativo para melhorar contraste
|
11 |
"""
|
12 |
+
lab = cv2.cvtColor(imagem, cv2.COLOR_RGB2LAB)
|
13 |
+
l, a, b = cv2.split(lab)
|
14 |
+
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
|
15 |
+
l = clahe.apply(l)
|
16 |
+
lab = cv2.merge((l,a,b))
|
17 |
+
return cv2.cvtColor(lab, cv2.COLOR_LAB2RGB)
|
18 |
+
|
19 |
+
def detectar_pupila_iris(imagem):
|
20 |
+
"""
|
21 |
+
Detecta pupila e íris com técnicas avançadas
|
22 |
+
"""
|
23 |
+
# Melhorar contraste
|
24 |
+
imagem_melhorada = melhorar_contraste(imagem)
|
25 |
+
|
26 |
# Converter para escala de cinza
|
27 |
+
gray = cv2.cvtColor(imagem_melhorada, cv2.COLOR_RGB2GRAY)
|
28 |
|
29 |
# Aplicar blur para reduzir ruído
|
30 |
blur = cv2.GaussianBlur(gray, (7, 7), 0)
|
31 |
|
32 |
+
# Detectar bordas
|
33 |
+
edges = cv2.Canny(blur, 30, 60)
|
34 |
+
|
35 |
+
# Aplicar fechamento morfológico para conectar bordas
|
36 |
+
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
|
37 |
+
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
|
38 |
+
|
39 |
+
# Detectar círculos para pupila (menores)
|
40 |
+
pupila_circles = cv2.HoughCircles(
|
41 |
+
closed,
|
42 |
cv2.HOUGH_GRADIENT,
|
43 |
dp=1,
|
44 |
minDist=50,
|
45 |
param1=50,
|
46 |
+
param2=25,
|
47 |
+
minRadius=20,
|
48 |
+
maxRadius=50
|
49 |
+
)
|
50 |
+
|
51 |
+
# Detectar círculos para íris (maiores)
|
52 |
+
iris_circles = cv2.HoughCircles(
|
53 |
+
closed,
|
54 |
+
cv2.HOUGH_GRADIENT,
|
55 |
+
dp=1,
|
56 |
+
minDist=100,
|
57 |
+
param1=50,
|
58 |
param2=30,
|
59 |
+
minRadius=80,
|
60 |
maxRadius=150
|
61 |
)
|
62 |
|
63 |
+
output_img = imagem.copy()
|
64 |
+
|
65 |
+
# Desenhar círculos da pupila
|
66 |
+
if pupila_circles is not None:
|
67 |
+
pupila_circles = np.uint16(np.around(pupila_circles))
|
68 |
+
for i in pupila_circles[0,:]:
|
69 |
+
# Desenhar círculo da pupila
|
70 |
+
cv2.circle(output_img, (i[0], i[1]), i[2], (255, 0, 0), 2)
|
71 |
+
# Desenhar centro
|
72 |
+
cv2.circle(output_img, (i[0], i[1]), 2, (0, 0, 255), 3)
|
73 |
+
pupila_info = (i[0], i[1], i[2])
|
74 |
+
else:
|
75 |
+
pupila_info = None
|
76 |
+
|
77 |
+
# Desenhar círculos da íris
|
78 |
+
if iris_circles is not None:
|
79 |
+
iris_circles = np.uint16(np.around(iris_circles))
|
80 |
+
for i in iris_circles[0,:]:
|
81 |
+
# Desenhar círculo da íris
|
82 |
+
cv2.circle(output_img, (i[0], i[1]), i[2], (0, 255, 0), 2)
|
83 |
+
iris_info = (i[0], i[1], i[2])
|
84 |
+
|
85 |
+
# Desenhar setores da íris
|
86 |
+
ang_step = 45
|
87 |
+
for ang in range(0, 360, ang_step):
|
88 |
+
end_x = int(i[0] + i[2] * np.cos(np.radians(ang)))
|
89 |
+
end_y = int(i[1] + i[2] * np.sin(np.radians(ang)))
|
90 |
+
cv2.line(output_img, (i[0], i[1]), (end_x, end_y), (0, 255, 0), 1)
|
91 |
+
else:
|
92 |
+
iris_info = None
|
93 |
+
|
94 |
+
return output_img, pupila_info, iris_info
|
95 |
|
96 |
+
def extrair_caracteristicas_avancadas(imagem, pupila_info, iris_info):
|
97 |
"""
|
98 |
+
Extrai características avançadas da íris usando a posição da pupila
|
99 |
"""
|
100 |
+
if pupila_info is None or iris_info is None:
|
101 |
return {}
|
102 |
|
103 |
# Converter para escala de cinza
|
104 |
+
gray = cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
+
# Coordenadas da pupila e íris
|
107 |
+
px, py, pr = pupila_info
|
108 |
+
ix, iy, ir = iris_info
|
109 |
|
110 |
+
# Criar máscara anelar (região entre pupila e íris)
|
111 |
+
mask = np.zeros_like(gray)
|
112 |
+
cv2.circle(mask, (ix, iy), ir, 255, -1) # Íris
|
113 |
+
cv2.circle(mask, (px, py), pr, 0, -1) # Pupila
|
114 |
|
115 |
+
# Aplicar máscara
|
116 |
+
iris_ring = cv2.bitwise_and(gray, gray, mask=mask)
|
117 |
|
118 |
+
# Análise de textura
|
119 |
+
caracteristicas = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
+
# Divisão em setores
|
122 |
setores = {
|
123 |
+
"superior": (315, 45),
|
124 |
+
"direito": (45, 135),
|
125 |
+
"inferior": (135, 225),
|
126 |
+
"esquerdo": (225, 315)
|
127 |
}
|
128 |
|
|
|
|
|
129 |
for setor, (ang_inicio, ang_fim) in setores.items():
|
130 |
+
# Criar máscara do setor
|
131 |
+
setor_mask = np.zeros_like(gray)
|
132 |
+
cv2.ellipse(setor_mask,
|
133 |
+
(ix, iy),
|
134 |
+
(ir, ir),
|
135 |
+
0,
|
136 |
+
ang_inicio,
|
137 |
+
ang_fim,
|
138 |
+
255,
|
139 |
-1)
|
140 |
|
141 |
+
# Aplicar máscara do setor
|
142 |
+
setor_roi = cv2.bitwise_and(iris_ring, iris_ring, mask=setor_mask)
|
143 |
|
144 |
+
# Análises no setor
|
145 |
+
non_zero = setor_roi[setor_roi != 0]
|
146 |
+
if len(non_zero) > 0:
|
147 |
+
caracteristicas[setor] = {
|
148 |
+
"media": np.mean(non_zero),
|
149 |
+
"std": np.std(non_zero),
|
150 |
+
"min": np.min(non_zero),
|
151 |
+
"max": np.max(non_zero)
|
152 |
+
}
|
153 |
+
|
154 |
+
return caracteristicas
|
155 |
|
156 |
+
def analisar_padrao_collarette(imagem, pupila_info, iris_info):
|
157 |
"""
|
158 |
+
Analisa o padrão do collarette (anel ao redor da pupila)
|
159 |
"""
|
160 |
+
if pupila_info is None or iris_info is None:
|
161 |
+
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
+
px, py, pr = pupila_info
|
164 |
+
ix, iy, ir = iris_info
|
|
|
|
|
165 |
|
166 |
+
# Região do collarette (aprox. 1/3 da distância entre pupila e íris)
|
167 |
+
collarette_r = pr + int((ir - pr) * 0.33)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
+
# Criar máscara anelar para o collarette
|
170 |
+
mask = np.zeros_like(cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY))
|
171 |
+
cv2.circle(mask, (px, py), collarette_r, 255, -1)
|
172 |
+
cv2.circle(mask, (px, py), pr, 0, -1)
|
|
|
|
|
|
|
|
|
173 |
|
174 |
+
# Aplicar máscara
|
175 |
+
collarette = cv2.bitwise_and(imagem, imagem, mask=mask)
|
|
|
|
|
176 |
|
177 |
+
# Análise do collarette
|
178 |
+
gray_collarette = cv2.cvtColor(collarette, cv2.COLOR_RGB2GRAY)
|
179 |
+
non_zero = gray_collarette[gray_collarette != 0]
|
180 |
|
181 |
+
if len(non_zero) > 0:
|
182 |
+
return {
|
183 |
+
"intensidade_media": np.mean(non_zero),
|
184 |
+
"variacao": np.std(non_zero),
|
185 |
+
"regularidade": cv2.Laplacian(gray_collarette, cv2.CV_64F).var()
|
186 |
+
}
|
187 |
|
188 |
+
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
def criar_interface():
|
191 |
"""
|
192 |
+
Cria interface do Gradio com tema verde piscina
|
193 |
"""
|
|
|
194 |
theme = gr.themes.Soft(
|
195 |
primary_hue="teal",
|
196 |
secondary_hue="green",
|
|
|
203 |
button_primary_background_fill_dark="#264653",
|
204 |
)
|
205 |
|
206 |
+
def processar_imagem(imagem):
|
207 |
+
# Detectar pupila e íris
|
208 |
+
output_img, pupila_info, iris_info = detectar_pupila_iris(imagem)
|
209 |
+
|
210 |
+
if pupila_info is None or iris_info is None:
|
211 |
+
return output_img, "Não foi possível detectar pupila ou íris corretamente."
|
212 |
+
|
213 |
+
# Extrair características
|
214 |
+
caracteristicas = extrair_caracteristicas_avancadas(imagem, pupila_info, iris_info)
|
215 |
+
|
216 |
+
# Analisar collarette
|
217 |
+
collarette_info = analisar_padrao_collarette(imagem, pupila_info, iris_info)
|
218 |
+
|
219 |
+
# Gerar relatório
|
220 |
+
relatorio = "ANÁLISE IRIDOLÓGICA DETALHADA\n\n"
|
221 |
+
|
222 |
+
# Informações da pupila
|
223 |
+
px, py, pr = pupila_info
|
224 |
+
relatorio += f"Pupila:\n"
|
225 |
+
relatorio += f"- Centro: ({px}, {py})\n"
|
226 |
+
relatorio += f"- Raio: {pr}px\n"
|
227 |
+
|
228 |
+
# Informações da íris
|
229 |
+
ix, iy, ir = iris_info
|
230 |
+
relatorio += f"\nÍris:\n"
|
231 |
+
relatorio += f"- Centro: ({ix}, {iy})\n"
|
232 |
+
relatorio += f"- Raio: {ir}px\n"
|
233 |
+
|
234 |
+
# Análise por setores
|
235 |
+
relatorio += "\nAnálise por Setores:\n"
|
236 |
+
for setor, dados in caracteristicas.items():
|
237 |
+
relatorio += f"\n{setor.title()}:\n"
|
238 |
+
relatorio += f"- Intensidade média: {dados['media']:.1f}\n"
|
239 |
+
relatorio += f"- Variação: {dados['std']:.1f}\n"
|
240 |
+
|
241 |
+
# Interpretar dados
|
242 |
+
if dados['std'] > 40:
|
243 |
+
relatorio += " * Alta variação - possível inflamação\n"
|
244 |
+
if dados['media'] < 100:
|
245 |
+
relatorio += " * Baixa intensidade - possível deficiência\n"
|
246 |
+
|
247 |
+
# Análise do collarette
|
248 |
+
if collarette_info:
|
249 |
+
relatorio += "\nAnálise do Collarette:\n"
|
250 |
+
if collarette_info['regularidade'] > 500:
|
251 |
+
relatorio += "- Irregularidade significativa\n"
|
252 |
+
if collarette_info['variacao'] > 30:
|
253 |
+
relatorio += "- Alta variação de textura\n"
|
254 |
+
|
255 |
+
return output_img, relatorio
|
256 |
+
|
257 |
# Interface
|
258 |
+
with gr.Blocks(theme=theme, title="Análise Iridológica Avançada") as interface:
|
259 |
gr.Markdown("""
|
260 |
# Sistema Avançado de Análise Iridológica
|
261 |
+
### Detecção precisa de pupila e íris com análise setorial
|
262 |
""")
|
263 |
|
264 |
with gr.Tabs():
|
|
|
268 |
with gr.Column():
|
269 |
input_image = gr.Image(
|
270 |
label="Imagem da Íris",
|
271 |
+
type="numpy"
|
272 |
)
|
273 |
with gr.Column():
|
274 |
output_image = gr.Image(
|
275 |
+
label="Análise Visual"
|
276 |
)
|
277 |
|
278 |
analysis_btn = gr.Button("Analisar Íris", variant="primary")
|
279 |
output_text = gr.Textbox(
|
280 |
+
label="Relatório de Análise",
|
281 |
+
lines=15
|
282 |
)
|
283 |
|
284 |
analysis_btn.click(
|
|
|
287 |
outputs=[output_image, output_text]
|
288 |
)
|
289 |
|
290 |
+
# Aba de Informações
|
291 |
+
with gr.Tab("Guia de Captura"):
|
292 |
gr.Markdown("""
|
293 |
+
## Guia para Captura de Imagem
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
|
295 |
+
### Requisitos da Imagem
|
296 |
+
1. **Iluminação**
|
297 |
+
- Luz uniforme
|
298 |
+
- Sem reflexos na pupila
|
299 |
+
- Sem sombras fortes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
|
301 |
2. **Posicionamento**
|
302 |
- Olho bem aberto
|
303 |
+
- Íris centralizada
|
304 |
+
- Foco na íris
|
305 |
+
|
306 |
+
3. **Qualidade**
|
307 |
+
- Alta resolução
|
308 |
+
- Imagem nítida
|
309 |
+
- Sem borramento
|
310 |
|
311 |
+
### Dicas de Captura
|
312 |
+
- Use luz natural indireta
|
313 |
+
- Mantenha a câmera estável
|
314 |
+
- Capture múltiplas fotos
|
315 |
+
- Verifique o foco antes
|
316 |
""")
|
317 |
|
318 |
return interface
|