DHEIVER commited on
Commit
fa76931
·
verified ·
1 Parent(s): 5a2b86b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +317 -182
app.py CHANGED
@@ -4,53 +4,69 @@ import numpy as np
4
  from PIL import Image
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,
@@ -60,76 +76,72 @@ def detectar_pupila_iris(imagem):
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,
@@ -138,58 +150,90 @@ def extrair_caracteristicas_avancadas(imagem, pupila_info, iris_info):
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",
@@ -204,70 +248,100 @@ def criar_interface():
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():
265
- # Aba de Análise
266
  with gr.Tab("Análise de Imagem"):
267
  with gr.Row():
268
  with gr.Column():
269
  input_image = gr.Image(
270
- label="Imagem da Íris",
271
  type="numpy"
272
  )
273
  with gr.Column():
@@ -275,10 +349,10 @@ def criar_interface():
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,36 +361,97 @@ def criar_interface():
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
319
 
320
- if __name__ == "__main__":
321
  interface = criar_interface()
322
- interface.launch(share=True)
 
 
 
 
4
  from PIL import Image
5
  import io
6
  from collections import defaultdict
7
+ from scipy import ndimage
8
 
9
+ def pre_processar_imagem(imagem):
10
  """
11
+ Pré-processamento avançado da imagem
12
  """
13
+ # Converter para LAB para melhor separação de cores
14
  lab = cv2.cvtColor(imagem, cv2.COLOR_RGB2LAB)
15
  l, a, b = cv2.split(lab)
16
+
17
+ # Aplicar CLAHE no canal L
18
  clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
19
  l = clahe.apply(l)
20
+
21
+ # Recombinar canais
22
  lab = cv2.merge((l,a,b))
23
+
24
+ # Converter de volta para RGB
25
+ imagem_melhorada = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB)
26
+
27
+ # Redução de ruído
28
+ imagem_melhorada = cv2.GaussianBlur(imagem_melhorada, (5, 5), 0)
29
+
30
+ return imagem_melhorada
31
 
32
+ def detectar_esclera(imagem):
33
  """
34
+ Detecta a região da esclera usando segmentação por cor e morfologia
35
  """
36
+ # Converter para HSV
37
+ hsv = cv2.cvtColor(imagem, cv2.COLOR_RGB2HSV)
38
 
39
+ # Definir faixa de cor para branco (esclera)
40
+ lower_white = np.array([0, 0, 180])
41
+ upper_white = np.array([180, 30, 255])
42
 
43
+ # Criar máscara
44
+ mask_esclera = cv2.inRange(hsv, lower_white, upper_white)
45
 
46
+ # Operações morfológicas para limpar
47
+ kernel = np.ones((5,5), np.uint8)
48
+ mask_esclera = cv2.morphologyEx(mask_esclera, cv2.MORPH_OPEN, kernel)
49
+ mask_esclera = cv2.morphologyEx(mask_esclera, cv2.MORPH_CLOSE, kernel)
50
+
51
+ return mask_esclera
52
+
53
+ def detectar_iris_pupila(imagem, mask_esclera):
54
+ """
55
+ Detecta íris e pupila usando múltiplas técnicas
56
+ """
57
+ # Converter para escala de cinza
58
+ gray = cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY)
59
 
60
+ # Aplicar máscara da esclera invertida
61
+ mask_olho = cv2.bitwise_not(mask_esclera)
62
+ eye_region = cv2.bitwise_and(gray, gray, mask=mask_olho)
63
 
64
+ # Detectar bordas
65
+ edges = cv2.Canny(eye_region, 30, 60)
 
 
 
 
 
 
 
 
 
66
 
67
+ # Detectar círculos para íris
68
  iris_circles = cv2.HoughCircles(
69
+ edges,
70
  cv2.HOUGH_GRADIENT,
71
  dp=1,
72
  minDist=100,
 
76
  maxRadius=150
77
  )
78
 
79
+ # Criar máscara da íris
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  if iris_circles is not None:
81
  iris_circles = np.uint16(np.around(iris_circles))
82
+ ix, iy, ir = iris_circles[0][0]
83
+ mask_iris = np.zeros_like(gray)
84
+ cv2.circle(mask_iris, (ix, iy), ir, 255, -1)
85
+
86
+ # Região dentro da íris para detecção da pupila
87
+ iris_region = cv2.bitwise_and(gray, gray, mask=mask_iris)
88
+
89
+ # Threshold adaptativo para pupila
90
+ thresh = cv2.adaptiveThreshold(
91
+ iris_region,
92
+ 255,
93
+ cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
94
+ cv2.THRESH_BINARY_INV,
95
+ 11,
96
+ 2
97
+ )
98
+
99
+ # Detectar pupila
100
+ pupil_circles = cv2.HoughCircles(
101
+ thresh,
102
+ cv2.HOUGH_GRADIENT,
103
+ dp=1,
104
+ minDist=50,
105
+ param1=50,
106
+ param2=25,
107
+ minRadius=20,
108
+ maxRadius=50
109
+ )
110
+
111
+ if pupil_circles is not None:
112
+ pupil_circles = np.uint16(np.around(pupil_circles))
113
+ px, py, pr = pupil_circles[0][0]
114
+ return (ix, iy, ir), (px, py, pr)
115
 
116
+ return None, None
117
 
118
+ def analisar_textura_setorial(imagem, iris_info, pupil_info):
119
  """
120
+ Analisa a textura da íris por setores
121
  """
122
+ if iris_info is None or pupil_info is None:
123
  return {}
124
 
 
 
 
 
 
125
  ix, iy, ir = iris_info
126
+ px, py, pr = pupil_info
127
 
128
+ # Converter para escala de cinza
129
+ gray = cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY)
 
 
 
 
 
 
 
 
130
 
131
+ # Criar máscara anelar da íris
132
+ mask_iris = np.zeros_like(gray)
133
+ cv2.circle(mask_iris, (ix, iy), ir, 255, -1)
134
+ cv2.circle(mask_iris, (px, py), pr, 0, -1)
 
 
 
135
 
136
+ # Dividir em 12 setores (como um relógio)
137
+ setores = {}
138
+ for i in range(12):
139
+ ang_inicio = i * 30
140
+ ang_fim = (i + 1) * 30
141
+
142
  # Criar máscara do setor
143
+ mask_setor = np.zeros_like(gray)
144
+ cv2.ellipse(mask_setor,
145
  (ix, iy),
146
  (ir, ir),
147
  0,
 
150
  255,
151
  -1)
152
 
153
+ # Combinar máscaras
154
+ mask_final = cv2.bitwise_and(mask_iris, mask_setor)
155
 
156
+ # Extrair região do setor
157
+ setor_roi = cv2.bitwise_and(gray, gray, mask=mask_final)
158
+
159
+ # Análise de textura
160
  non_zero = setor_roi[setor_roi != 0]
161
  if len(non_zero) > 0:
162
+ # Calcular características de textura
163
+ glcm = graycomatrix(non_zero.reshape(-1, 1), [1], [0], symmetric=True, normed=True)
164
+
165
+ setores[f"setor_{i+1}"] = {
166
  "media": np.mean(non_zero),
167
  "std": np.std(non_zero),
168
+ "contraste": graycoprops(glcm, 'contrast')[0, 0],
169
+ "homogeneidade": graycoprops(glcm, 'homogeneity')[0, 0],
170
+ "energia": graycoprops(glcm, 'energy')[0, 0],
171
+ "correlacao": graycoprops(glcm, 'correlation')[0, 0]
172
  }
173
 
174
+ return setores
175
 
176
+ def analisar_collarette(imagem, iris_info, pupil_info):
177
  """
178
+ Analisa o collarette (anel de contração) em detalhes
179
  """
180
+ if iris_info is None or pupil_info is None:
181
  return None
182
 
 
183
  ix, iy, ir = iris_info
184
+ px, py, pr = pupil_info
185
 
186
+ # Distância entre pupila e íris
187
+ dist = ir - pr
188
 
189
+ # Região do collarette (aproximadamente 35% da distância)
190
+ collarette_inner = pr + int(dist * 0.25)
191
+ collarette_outer = pr + int(dist * 0.45)
192
+
193
+ # Criar máscara do collarette
194
  mask = np.zeros_like(cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY))
195
+ cv2.circle(mask, (px, py), collarette_outer, 255, -1)
196
+ cv2.circle(mask, (px, py), collarette_inner, 0, -1)
197
 
198
+ # Extrair região do collarette
199
+ collarette_region = cv2.bitwise_and(imagem, imagem, mask=mask)
200
 
201
+ # Análise detalhada
202
+ gray_collarette = cv2.cvtColor(collarette_region, cv2.COLOR_RGB2GRAY)
203
  non_zero = gray_collarette[gray_collarette != 0]
204
 
205
  if len(non_zero) > 0:
206
+ # Calcular características
207
+ glcm = graycomatrix(non_zero.reshape(-1, 1), [1], [0], symmetric=True, normed=True)
208
+
209
  return {
210
  "intensidade_media": np.mean(non_zero),
211
  "variacao": np.std(non_zero),
212
+ "contraste": graycoprops(glcm, 'contrast')[0, 0],
213
+ "homogeneidade": graycoprops(glcm, 'homogeneity')[0, 0],
214
+ "regularidade": cv2.Laplacian(gray_collarette, cv2.CV_64F).var(),
215
+ "circularidade": avaliar_circularidade(mask)
216
  }
217
 
218
  return None
219
 
220
+ def avaliar_circularidade(mask):
221
+ """
222
+ Avalia a circularidade de uma região
223
+ """
224
+ contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
225
+ if contours:
226
+ cnt = max(contours, key=cv2.contourArea)
227
+ area = cv2.contourArea(cnt)
228
+ perimeter = cv2.arcLength(cnt, True)
229
+ if perimeter > 0:
230
+ circularity = 4 * np.pi * area / (perimeter * perimeter)
231
+ return circularity
232
+ return 0
233
+
234
  def criar_interface():
235
  """
236
+ Cria interface moderna do Gradio
237
  """
238
  theme = gr.themes.Soft(
239
  primary_hue="teal",
 
248
  )
249
 
250
  def processar_imagem(imagem):
251
+ try:
252
+ # Pré-processamento
253
+ imagem_processada = pre_processar_imagem(imagem)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
+ # Detectar esclera
256
+ mask_esclera = detectar_esclera(imagem_processada)
257
+
258
+ # Detectar íris e pupila
259
+ iris_info, pupil_info = detectar_iris_pupila(imagem_processada, mask_esclera)
260
+
261
+ if iris_info is None or pupil_info is None:
262
+ return imagem, "Não foi possível detectar íris ou pupila corretamente."
263
+
264
+ # Análise de textura
265
+ analise_setorial = analisar_textura_setorial(imagem_processada, iris_info, pupil_info)
266
+
267
+ # Análise do collarette
268
+ info_collarette = analisar_collarette(imagem_processada, iris_info, pupil_info)
269
+
270
+ # Criar visualização
271
+ output_img = imagem.copy()
272
+
273
+ # Desenhar esclera
274
+ contours, _ = cv2.findContours(mask_esclera, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
275
+ cv2.drawContours(output_img, contours, -1, (255, 255, 0), 1)
276
+
277
+ # Desenhar íris
278
+ ix, iy, ir = iris_info
279
+ cv2.circle(output_img, (ix, iy), ir, (0, 255, 0), 2)
280
+
281
+ # Desenhar pupila
282
+ px, py, pr = pupil_info
283
+ cv2.circle(output_img, (px, py), pr, (255, 0, 0), 2)
284
+
285
+ # Desenhar setores
286
+ for i in range(12):
287
+ ang = i * 30
288
+ rad = np.radians(ang)
289
+ end_x = int(ix + ir * np.cos(rad))
290
+ end_y = int(iy + ir * np.sin(rad))
291
+ cv2.line(output_img, (ix, iy), (end_x, end_y), (0, 255, 0), 1)
292
+
293
+ # Gerar relatório
294
+ relatorio = "ANÁLISE IRIDOLÓGICA DETALHADA\n\n"
295
+
296
+ # Informações estruturais
297
+ relatorio += "1. MEDIDAS ESTRUTURAIS\n"
298
+ relatorio += f"Pupila: Centro ({px}, {py}), Raio {pr}px\n"
299
+ relatorio += f"Íris: Centro ({ix}, {iy}), Raio {ir}px\n"
300
+
301
+ # Análise setorial
302
+ relatorio += "\n2. ANÁLISE SETORIAL\n"
303
+ for setor, dados in analise_setorial.items():
304
+ relatorio += f"\n{setor}:\n"
305
+ relatorio += f"- Contraste: {dados['contraste']:.2f}\n"
306
+ relatorio += f"- Homogeneidade: {dados['homogeneidade']:.2f}\n"
307
+
308
+ # Interpretação
309
+ if dados['contraste'] > 2.0:
310
+ relatorio += " * Alta densidade de sinais\n"
311
+ if dados['homogeneidade'] < 0.5:
312
+ relatorio += " * Possível área de alteração\n"
313
+
314
+ # Análise do collarette
315
+ if info_collarette:
316
+ relatorio += "\n3. ANÁLISE DO COLLARETTE\n"
317
+ relatorio += f"- Regularidade: {info_collarette['regularidade']:.2f}\n"
318
+ relatorio += f"- Circularidade: {info_collarette['circularidade']:.2f}\n"
319
+
320
+ # Interpretação
321
+ if info_collarette['regularidade'] > 500:
322
+ relatorio += " * Irregularidade significativa\n"
323
+ if info_collarette['circularidade'] < 0.8:
324
+ relatorio += " * Possível deformação estrutural\n"
325
+
326
+ return output_img, relatorio
327
+
328
+ except Exception as e:
329
+ return imagem, f"Erro durante o processamento: {str(e)}"
330
 
331
  # Interface
332
  with gr.Blocks(theme=theme, title="Análise Iridológica Avançada") as interface:
333
  gr.Markdown("""
334
  # Sistema Avançado de Análise Iridológica
335
+ ### Detecção precisa de esclera, íris e pupila com análise setorial
336
  """)
337
 
338
  with gr.Tabs():
339
+ # Aba de Análise Principal
340
  with gr.Tab("Análise de Imagem"):
341
  with gr.Row():
342
  with gr.Column():
343
  input_image = gr.Image(
344
+ label="Imagem do Olho",
345
  type="numpy"
346
  )
347
  with gr.Column():
 
349
  label="Análise Visual"
350
  )
351
 
352
+ analysis_btn = gr.Button("Analisar Olho", variant="primary")
353
  output_text = gr.Textbox(
354
  label="Relatório de Análise",
355
+ lines=20
356
  )
357
 
358
  analysis_btn.click(
 
361
  outputs=[output_image, output_text]
362
  )
363
 
364
+ # Aba de Configurações
365
+ with gr.Tab("Configurações"):
366
+ with gr.Row():
367
+ min_iris_radius = gr.Slider(
368
+ minimum=60,
369
+ maximum=200,
370
+ value=80,
371
+ label="Raio Mínimo da Íris (px)"
372
+ )
373
+ max_iris_radius = gr.Slider(
374
+ minimum=100,
375
+ maximum=250,
376
+ value=150,
377
+ label="Raio Máximo da Íris (px)"
378
+ )
379
+
380
+ with gr.Row():
381
+ min_pupil_radius = gr.Slider(
382
+ minimum=15,
383
+ maximum=70,
384
+ value=20,
385
+ label="Raio Mínimo da Pupila (px)"
386
+ )
387
+ max_pupil_radius = gr.Slider(
388
+ minimum=30,
389
+ maximum=100,
390
+ value=50,
391
+ label="Raio Máximo da Pupila (px)"
392
+ )
393
+
394
+ # Aba de Guia de Captura
395
  with gr.Tab("Guia de Captura"):
396
  gr.Markdown("""
397
  ## Guia para Captura de Imagem
398
 
399
+ ### 1. Iluminação Ideal
400
+ - Luz natural indireta
401
+ - Sem reflexos diretos no olho
402
+ - Iluminação uniforme
403
+ - Evitar flash
404
 
405
+ ### 2. Posicionamento
406
+ - Olho totalmente aberto
407
+ - Câmera perpendicular ao olho
408
+ - Distância adequada (15-20cm)
409
+ - Íris centralizada na imagem
410
 
411
+ ### 3. Qualidade da Imagem
412
+ - Resolução mínima: 1280x720
413
+ - Foco perfeito na íris
414
+ - Sem movimento/tremor
415
+ - Imagem nítida e clara
416
 
417
+ ### 4. Preparação
418
+ - Limpar a lente da câmera
419
+ - Olho descansado
420
+ - Ambiente calmo
421
+ - Múltiplas capturas
422
+ """)
423
+
424
+ # Aba de Interpretação
425
+ with gr.Tab("Guia de Interpretação"):
426
+ gr.Markdown("""
427
+ ## Guia de Interpretação dos Resultados
428
+
429
+ ### 1. Análise da Pupila
430
+ - **Tamanho**: Indica atividade do sistema nervoso
431
+ - **Forma**: Regular ou irregular
432
+ - **Posição**: Centralizada ou deslocada
433
+
434
+ ### 2. Análise da Íris
435
+ - **Densidade**: Integridade do tecido
436
+ - **Coloração**: Atividade metabólica
437
+ - **Textura**: Estado geral dos tecidos
438
+
439
+ ### 3. Sinais Específicos
440
+ - **Lacunas**: Possíveis deficiências
441
+ - **Manchas**: Toxicidade ou inflamação
442
+ - **Anéis**: Tensão ou congestão
443
+
444
+ ### 4. Collarette
445
+ - **Regularidade**: Equilíbrio do sistema
446
+ - **Circularidade**: Integridade estrutural
447
+ - **Densidade**: Vitalidade geral
448
  """)
449
 
450
  return interface
451
 
452
+ def main():
453
  interface = criar_interface()
454
+ interface.launch(share=True)
455
+
456
+ if __name__ == "__main__":
457
+ main()