DHEIVER commited on
Commit
a8affc3
·
verified ·
1 Parent(s): 44ecdae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -124
app.py CHANGED
@@ -193,13 +193,100 @@ class IrisAnalyzer:
193
  )
194
  ]
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  def analyze_iris(self, image: np.ndarray) -> Dict:
197
- # Converter para diferentes espaços de cor para análise mais completa
198
  gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
199
  hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
200
  lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB)
201
 
202
- # Detectar centro e borda da íris usando Hough Circles
203
  circles = cv2.HoughCircles(
204
  gray, cv2.HOUGH_GRADIENT, dp=1, minDist=100,
205
  param1=50, param2=30, minRadius=50, maxRadius=150
@@ -226,12 +313,10 @@ class IrisAnalyzer:
226
  inner_r = int(radius * zone.ratio[0])
227
  outer_r = int(radius * zone.ratio[1])
228
 
229
- # Criar máscaras para diferentes análises
230
  mask = np.zeros(gray.shape, dtype=np.uint8)
231
  cv2.circle(mask, center, outer_r, 255, -1)
232
  cv2.circle(mask, center, inner_r, 0, -1)
233
 
234
- # Análise multiespectral
235
  zone_metrics = {
236
  "intensity": cv2.mean(gray, mask=mask)[0],
237
  "saturation": cv2.mean(hsv[..., 1], mask=mask)[0],
@@ -240,7 +325,6 @@ class IrisAnalyzer:
240
  "patterns": self._detect_patterns(gray, mask)
241
  }
242
 
243
- # Análise detalhada baseada em múltiplos fatores
244
  health_score = (
245
  zone_metrics["intensity"] * 0.3 +
246
  zone_metrics["saturation"] * 0.2 +
@@ -271,7 +355,6 @@ class IrisAnalyzer:
271
  "confianca_analise": self._calculate_confidence(zone_metrics)
272
  }
273
 
274
- # Marcar zona na imagem
275
  cv2.circle(image, center, outer_r, zone.color, 2)
276
  cv2.putText(image, zone.name,
277
  (center[0]-outer_r, center[1]+outer_r),
@@ -279,111 +362,7 @@ class IrisAnalyzer:
279
 
280
  return image, results
281
 
282
- def _customize_conditions(self, base_conditions: List[str], metrics: Dict) -> List[str]:
283
- """Personaliza as condições baseado nas métricas específicas"""
284
- customized = []
285
- for condition in base_conditions:
286
- # Adicionar detalhes específicos baseados nas métricas
287
- if metrics["intensity"] < 50:
288
- condition += " (intensidade muito baixa)"
289
- elif metrics["contrast"] < 30:
290
- condition += " (baixo contraste)"
291
-
292
- if metrics["patterns"] > 70:
293
- condition += " (padrões significativos detectados)"
294
-
295
- customized.append(condition)
296
- return customized
297
-
298
- def _customize_recommendations(self, base_recommendations: List[str], metrics: Dict) -> List[str]:
299
- """Personaliza as recomendações baseado nas métricas específicas"""
300
- customized = []
301
- for rec in base_recommendations:
302
- # Adicionar detalhes específicos baseados nas métricas
303
- if metrics["texture"] < 40:
304
- rec += " (prioridade alta)"
305
- elif metrics["saturation"] < 50:
306
- rec += " (atenção especial necessária)"
307
-
308
- customized.append(rec)
309
- return customized
310
-
311
- def _calculate_confidence(self, metrics: Dict) -> str:
312
- """Calcula o nível de confiança da análise baseado nas métricas"""
313
- confidence_score = (
314
- metrics["intensity"] * 0.25 +
315
- metrics["contrast"] * 0.25 +
316
- metrics["texture"] * 0.25 +
317
- metrics["patterns"] * 0.25
318
- )
319
-
320
- if confidence_score > 75:
321
- return "alta"
322
- elif confidence_score > 50:
323
- return "média"
324
- else:
325
- return "baixa"
326
-
327
  def process_image(img):
328
- if img is None:
329
- return [None] * 5, gr.Warning("Por favor, carregue uma imagem.")
330
-
331
- analyzer = IrisAnalyzer()
332
- processed_img, results = analyzer.analyze_iris(img)
333
-
334
- # Relatório Geral
335
- general_report = "# 📊 Visão Geral da Análise\n\n"
336
- status_counts = {"baixa": 0, "media": 0, "alta": 0}
337
- for analysis in results["analysis"].values():
338
- status_counts[analysis["status"]] += 1
339
-
340
- health_score = ((status_counts["alta"] * 100) + (status_counts["media"] * 50)) / len(results["analysis"])
341
- general_report += f"**Índice de Saúde Geral:** {health_score:.1f}%\n\n"
342
- general_report += f"**Data da Análise:** {results['timestamp']}\n\n"
343
- general_report += "**Qualidade da Imagem:** {:.1f}%\n\n".format(results['metrics']['image_quality'])
344
-
345
- # Condições Detalhadas
346
- detailed_conditions = "# 🔍 Análise Detalhada por Zona\n\n"
347
- for zone_name, analysis in results["analysis"].items():
348
- detailed_conditions += f"## {zone_name}\n\n"
349
- detailed_conditions += "### Condições Identificadas:\n"
350
- for condition in analysis["conditions"]:
351
- detailed_conditions += f"- {condition}\n"
352
- detailed_conditions += f"\n**Status:** {analysis['status'].title()}\n"
353
- detailed_conditions += f"**Confiança da Análise:** {analysis['confianca_analise']}\n"
354
- detailed_conditions += "**Métricas Detalhadas:**\n"
355
- for metric, value in analysis["metrics"].items():
356
- detailed_conditions += f"- {metric.replace('_', ' ').title()}: {value:.1f}\n"
357
- detailed_conditions += "\n"
358
-
359
- # Recomendações
360
- recommendations = "# 💡 Recomendações Personalizadas\n\n"
361
- for zone_name, analysis in results["analysis"].items():
362
- recommendations += f"## {zone_name}\n\n"
363
- for rec in analysis["recommendations"]:
364
- recommendations += f"- {rec}\n"
365
- recommendations += "\n"
366
-
367
- # Alertas de Saúde
368
- health_alerts = "# ⚠️ Alertas e Atenção Especial\n\n"
369
- for zone_name, analysis in results["analysis"].items():
370
- if analysis["status"] == "baixa" or analysis["metrics"]["health_score"] < 50:
371
- health_alerts += f"## {zone_name}\n"
372
- health_alerts += "### Pontos de Atenção:\n"
373
- for condition in analysis["conditions"]:
374
- health_alerts += f"- ⚠️ {condition}\n"
375
- health_alerts += "\n### Ações Recomendadas:\n"
376
- for rec in analysis["recommendations"]:
377
- health_alerts += f"- ✅ {rec}\n"
378
- health_alerts += "\n"
379
-
380
- return [
381
- processed_img,
382
- general_report,
383
- detailed_conditions,
384
- recommendations,
385
- health_alerts
386
- ]
387
  if img is None:
388
  return [None] * 5, gr.Warning("Por favor, carregue uma imagem.")
389
 
@@ -399,29 +378,34 @@ def process_image(img):
399
  health_score = ((status_counts["alta"] * 100) + (status_counts["media"] * 50)) / len(results["analysis"])
400
  general_report += f"**Índice de Saúde Geral:** {health_score:.1f}%\n\n"
401
  general_report += f"**Data da Análise:** {results['timestamp']}\n\n"
 
402
 
403
  # Condições Detalhadas
404
  detailed_conditions = "# 🔍 Análise Detalhada por Zona\n\n"
 
 
 
405
  for zone_name, analysis in results["analysis"].items():
 
406
  detailed_conditions += f"## {zone_name}\n\n"
407
  detailed_conditions += "### Condições Identificadas:\n"
408
  for condition in analysis["conditions"]:
409
  detailed_conditions += f"- {condition}\n"
410
  detailed_conditions += f"\n**Status:** {analysis['status'].title()}\n"
411
- detailed_conditions += f"**Intensidade:** {analysis['intensity']:.1f}\n\n"
412
-
413
- # Recomendações
414
- recommendations = "# 💡 Recomendações Personalizadas\n\n"
415
- for zone_name, analysis in results["analysis"].items():
 
 
416
  recommendations += f"## {zone_name}\n\n"
417
  for rec in analysis["recommendations"]:
418
  recommendations += f"- {rec}\n"
419
  recommendations += "\n"
420
-
421
- # Alertas de Saúde
422
- health_alerts = "# ⚠️ Alertas e Atenção Especial\n\n"
423
- for zone_name, analysis in results["analysis"].items():
424
- if analysis["status"] == "baixa":
425
  health_alerts += f"## {zone_name}\n"
426
  health_alerts += "### Pontos de Atenção:\n"
427
  for condition in analysis["conditions"]:
@@ -439,7 +423,7 @@ def process_image(img):
439
  health_alerts
440
  ]
441
 
442
- # Interface Gradio moderna com Blocks
443
  with gr.Blocks(theme=gr.themes.Soft()) as iface:
444
  gr.Markdown("""
445
  # 🔍 Analisador Avançado de Íris
@@ -449,7 +433,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
449
  """)
450
 
451
  with gr.Tabs() as tabs:
452
- # Aba de Análise
453
  with gr.Tab("📸 Análise de Imagem", id=1):
454
  with gr.Row():
455
  with gr.Column(scale=1):
@@ -464,7 +447,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
464
  with gr.Column(scale=1):
465
  output_image = gr.Image(label="Visualização da Análise", height=400)
466
 
467
- # Aba de Resultados
468
  with gr.Tab("📊 Resultados", id=2):
469
  with gr.Tabs() as result_tabs:
470
  with gr.Tab("📈 Visão Geral", id=2.1):
@@ -479,7 +461,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
479
  with gr.Tab("⚠️ Alertas", id=2.4):
480
  alerts_output = gr.Markdown()
481
 
482
- # Aba de Informações
483
  with gr.Tab("ℹ️ Informações", id=3):
484
  gr.Markdown("""
485
  ## 📚 Sobre a Análise Iridológica
@@ -499,6 +480,12 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
499
  3. Verifique os resultados nas diferentes abas
500
  4. Consulte os alertas e recomendações
501
 
 
 
 
 
 
 
502
  ### ⚠️ Observações Importantes:
503
  - Sistema para fins educacionais
504
  - Não substitui avaliação médica
 
193
  )
194
  ]
195
 
196
+ def _assess_image_quality(self, image: np.ndarray) -> float:
197
+ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
198
+ blur_score = cv2.Laplacian(gray, cv2.CV_64F).var()
199
+ brightness = np.mean(gray)
200
+ contrast = np.std(gray)
201
+
202
+ quality_score = (
203
+ min(blur_score / 500, 1) * 0.4 +
204
+ min(abs(brightness - 128) / 128, 1) * 0.3 +
205
+ min(contrast / 50, 1) * 0.3
206
+ ) * 100
207
+
208
+ return quality_score
209
+
210
+ def _analyze_texture(self, gray: np.ndarray, mask: np.ndarray) -> float:
211
+ zone_pixels = cv2.bitwise_and(gray, gray, mask=mask)
212
+ if np.sum(mask) == 0:
213
+ return 0
214
+
215
+ mean = np.mean(zone_pixels[mask > 0])
216
+ std = np.std(zone_pixels[mask > 0])
217
+ entropy = np.sum(np.abs(np.diff(zone_pixels[mask > 0])))
218
+
219
+ texture_score = (mean * 0.3 + std * 0.3 + min(entropy/1000, 1) * 0.4) * 100
220
+ return min(texture_score, 100)
221
+
222
+ def _analyze_contrast(self, l_channel: np.ndarray, mask: np.ndarray) -> float:
223
+ if np.sum(mask) == 0:
224
+ return 0
225
+
226
+ zone_pixels = l_channel[mask > 0]
227
+ p5 = np.percentile(zone_pixels, 5)
228
+ p95 = np.percentile(zone_pixels, 95)
229
+
230
+ contrast_score = ((p95 - p5) / 255) * 100
231
+ return min(contrast_score, 100)
232
+
233
+ def _detect_patterns(self, gray: np.ndarray, mask: np.ndarray) -> float:
234
+ if np.sum(mask) == 0:
235
+ return 0
236
+
237
+ sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
238
+ sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
239
+ gradient = np.sqrt(sobelx**2 + sobely**2)
240
+
241
+ zone_gradient = gradient[mask > 0]
242
+ pattern_score = (np.mean(zone_gradient) / np.max(gradient)) * 100
243
+ return min(pattern_score, 100)
244
+
245
+ def _customize_conditions(self, base_conditions: List[str], metrics: Dict) -> List[str]:
246
+ customized = []
247
+ for condition in base_conditions:
248
+ if metrics["intensity"] < 50:
249
+ condition += " (intensidade muito baixa)"
250
+ elif metrics["contrast"] < 30:
251
+ condition += " (baixo contraste)"
252
+
253
+ if metrics["patterns"] > 70:
254
+ condition += " (padrões significativos detectados)"
255
+
256
+ customized.append(condition)
257
+ return customized
258
+
259
+ def _customize_recommendations(self, base_recommendations: List[str], metrics: Dict) -> List[str]:
260
+ customized = []
261
+ for rec in base_recommendations:
262
+ if metrics["texture"] < 40:
263
+ rec += " (prioridade alta)"
264
+ elif metrics["saturation"] < 50:
265
+ rec += " (atenção especial necessária)"
266
+
267
+ customized.append(rec)
268
+ return customized
269
+
270
+ def _calculate_confidence(self, metrics: Dict) -> str:
271
+ confidence_score = (
272
+ metrics["intensity"] * 0.25 +
273
+ metrics["contrast"] * 0.25 +
274
+ metrics["texture"] * 0.25 +
275
+ metrics["patterns"] * 0.25
276
+ )
277
+
278
+ if confidence_score > 75:
279
+ return "alta"
280
+ elif confidence_score > 50:
281
+ return "média"
282
+ else:
283
+ return "baixa"
284
+
285
  def analyze_iris(self, image: np.ndarray) -> Dict:
 
286
  gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
287
  hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
288
  lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB)
289
 
 
290
  circles = cv2.HoughCircles(
291
  gray, cv2.HOUGH_GRADIENT, dp=1, minDist=100,
292
  param1=50, param2=30, minRadius=50, maxRadius=150
 
313
  inner_r = int(radius * zone.ratio[0])
314
  outer_r = int(radius * zone.ratio[1])
315
 
 
316
  mask = np.zeros(gray.shape, dtype=np.uint8)
317
  cv2.circle(mask, center, outer_r, 255, -1)
318
  cv2.circle(mask, center, inner_r, 0, -1)
319
 
 
320
  zone_metrics = {
321
  "intensity": cv2.mean(gray, mask=mask)[0],
322
  "saturation": cv2.mean(hsv[..., 1], mask=mask)[0],
 
325
  "patterns": self._detect_patterns(gray, mask)
326
  }
327
 
 
328
  health_score = (
329
  zone_metrics["intensity"] * 0.3 +
330
  zone_metrics["saturation"] * 0.2 +
 
355
  "confianca_analise": self._calculate_confidence(zone_metrics)
356
  }
357
 
 
358
  cv2.circle(image, center, outer_r, zone.color, 2)
359
  cv2.putText(image, zone.name,
360
  (center[0]-outer_r, center[1]+outer_r),
 
362
 
363
  return image, results
364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  def process_image(img):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  if img is None:
367
  return [None] * 5, gr.Warning("Por favor, carregue uma imagem.")
368
 
 
378
  health_score = ((status_counts["alta"] * 100) + (status_counts["media"] * 50)) / len(results["analysis"])
379
  general_report += f"**Índice de Saúde Geral:** {health_score:.1f}%\n\n"
380
  general_report += f"**Data da Análise:** {results['timestamp']}\n\n"
381
+ general_report += "**Qualidade da Imagem:** {:.1f}%\n\n".format(results['metrics']['image_quality'])
382
 
383
  # Condições Detalhadas
384
  detailed_conditions = "# 🔍 Análise Detalhada por Zona\n\n"
385
+ recommendations = "# 💡 Recomendações Personalizadas\n\n"
386
+ health_alerts = "# ⚠️ Alertas e Atenção Especial\n\n"
387
+
388
  for zone_name, analysis in results["analysis"].items():
389
+ # Detailed conditions
390
  detailed_conditions += f"## {zone_name}\n\n"
391
  detailed_conditions += "### Condições Identificadas:\n"
392
  for condition in analysis["conditions"]:
393
  detailed_conditions += f"- {condition}\n"
394
  detailed_conditions += f"\n**Status:** {analysis['status'].title()}\n"
395
+ detailed_conditions += f"**Confiança da Análise:** {analysis['confianca_analise']}\n"
396
+ detailed_conditions += "**Métricas Detalhadas:**\n"
397
+ for metric, value in analysis["metrics"].items():
398
+ detailed_conditions += f"- {metric.replace('_', ' ').title()}: {value:.1f}\n"
399
+ detailed_conditions += "\n"
400
+
401
+ # Recommendations
402
  recommendations += f"## {zone_name}\n\n"
403
  for rec in analysis["recommendations"]:
404
  recommendations += f"- {rec}\n"
405
  recommendations += "\n"
406
+
407
+ # Health alerts
408
+ if analysis["status"] == "baixa" or analysis["metrics"]["health_score"] < 50:
 
 
409
  health_alerts += f"## {zone_name}\n"
410
  health_alerts += "### Pontos de Atenção:\n"
411
  for condition in analysis["conditions"]:
 
423
  health_alerts
424
  ]
425
 
426
+ # Interface Gradio
427
  with gr.Blocks(theme=gr.themes.Soft()) as iface:
428
  gr.Markdown("""
429
  # 🔍 Analisador Avançado de Íris
 
433
  """)
434
 
435
  with gr.Tabs() as tabs:
 
436
  with gr.Tab("📸 Análise de Imagem", id=1):
437
  with gr.Row():
438
  with gr.Column(scale=1):
 
447
  with gr.Column(scale=1):
448
  output_image = gr.Image(label="Visualização da Análise", height=400)
449
 
 
450
  with gr.Tab("📊 Resultados", id=2):
451
  with gr.Tabs() as result_tabs:
452
  with gr.Tab("📈 Visão Geral", id=2.1):
 
461
  with gr.Tab("⚠️ Alertas", id=2.4):
462
  alerts_output = gr.Markdown()
463
 
 
464
  with gr.Tab("ℹ️ Informações", id=3):
465
  gr.Markdown("""
466
  ## 📚 Sobre a Análise Iridológica
 
480
  3. Verifique os resultados nas diferentes abas
481
  4. Consulte os alertas e recomendações
482
 
483
+ ### 🔍 Interpretação dos Resultados:
484
+ - **Visão Geral**: Índice geral de saúde e qualidade da análise
485
+ - **Condições**: Análise detalhada por zona
486
+ - **Recomendações**: Sugestões personalizadas
487
+ - **Alertas**: Pontos que requerem atenção especial
488
+
489
  ### ⚠️ Observações Importantes:
490
  - Sistema para fins educacionais
491
  - Não substitui avaliação médica