import gradio as gr import cv2 import numpy as np from PIL import Image from dataclasses import dataclass from typing import Tuple, Dict, List import torch import torch.nn.functional as F import torchvision.transforms as transforms import logging from datetime import datetime import json # Configuração básica de logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) @dataclass class IrisZone: """Classe para definir as características de uma zona da íris""" name: str inner_ratio: float outer_ratio: float color: Tuple[int, int, int] description: str indicators: Dict[str, str] def __post_init__(self): if not 0 <= self.inner_ratio <= 1: raise ValueError("inner_ratio deve estar entre 0 e 1") if not 0 <= self.outer_ratio <= 1: raise ValueError("outer_ratio deve estar entre 0 e 1") if self.inner_ratio >= self.outer_ratio: raise ValueError("inner_ratio deve ser menor que outer_ratio") class IrisAnalysis: """Classe para análise e interpretação dos resultados""" @staticmethod def get_zone_interpretation(zone_name: str, intensity: float, variation: float) -> Dict: """Interpretação detalhada para cada zona""" base_interpretations = { "Zona Cerebral/Neural": { "aspectos": "Sistema nervoso central e periférico", "sistemas": ["Cérebro", "Medula espinhal", "Nervos"], "baixa": { "indicacao": "Possível fadiga neural", "sugestoes": [ "Considerar avaliação do sono", "Verificar níveis de estresse", "Avaliar demanda cognitiva" ] }, "média": { "indicacao": "Condição neural moderada", "sugestoes": [ "Manter boa higiene do sono", "Praticar atividades mentais" ] }, "alta": { "indicacao": "Boa vitalidade neural", "sugestoes": [ "Manter práticas saudáveis", "Continuar estimulação cognitiva" ] } }, "Zona Digestiva": { "aspectos": "Sistema digestivo completo", "sistemas": ["Estômago", "Intestinos", "Fígado", "Pâncreas"], "baixa": { "indicacao": "Possível sensibilidade digestiva", "sugestoes": [ "Avaliar hábitos alimentares", "Considerar diário alimentar", "Observar reações a alimentos" ] }, "média": { "indicacao": "Sistema digestivo em equilíbrio moderado", "sugestoes": [ "Manter alimentação balanceada", "Observar horários das refeições" ] }, "alta": { "indicacao": "Boa condição digestiva", "sugestoes": [ "Manter dieta equilibrada", "Continuar bons hábitos" ] } }, # [Definições similares para outras zonas...] } # Determinar nível baseado na intensidade if intensity < 85: nivel = "baixa" confianca = "reduzida" if variation > 30 else "moderada" elif intensity < 170: nivel = "média" confianca = "moderada" if variation > 20 else "alta" else: nivel = "alta" confianca = "alta" if variation < 15 else "moderada" zone_info = base_interpretations.get(zone_name, {}) return { "nome": zone_name, "aspectos_analisados": zone_info.get("aspectos", ""), "sistemas_relacionados": zone_info.get("sistemas", []), "interpretacao": zone_info.get(nivel, {}).get("indicacao", "Sem interpretação disponível"), "sugestoes": zone_info.get(nivel, {}).get("sugestoes", []), "metricas": { "intensidade": intensity, "variacao": variation, "nivel_geral": nivel, "confianca_analise": confianca, }, "indicadores": { "intensidade_valor": f"{intensity:.1f}/255", "variacao_valor": f"{variation:.1f}%", "homogeneidade": "Baixa" if variation > 30 else "Média" if variation > 15 else "Alta" } } class IrisAnalyzer: """Classe principal para análise da íris""" def __init__(self): self.zones = [ IrisZone( name="Zona Cerebral/Neural", inner_ratio=0.85, outer_ratio=1.0, color=(255, 0, 0), description="Sistema nervoso central e periférico", indicators={"estresse": "alto", "energia": "moderada"} ), # [Outras zonas definidas similarmente...] ] def preprocess_image(self, img: np.ndarray) -> np.ndarray: """Pré-processamento da imagem""" try: # Converter para LAB para melhor contraste lab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB) l, a, b = cv2.split(lab) # Aplicar CLAHE no canal L clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8)) l = clahe.apply(l) # Mesclar canais lab = cv2.merge((l,a,b)) enhanced = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB) # Redução de ruído denoised = cv2.fastNlMeansDenoisingColored(enhanced, None, 10, 10, 7, 21) return denoised except Exception as e: logging.error(f"Erro no pré-processamento: {str(e)}") return img def detect_pupil(self, img: np.ndarray) -> Tuple[int, int, int]: """Detecção avançada da pupila""" try: # Pré-processar imagem processed = self.preprocess_image(img) gray = cv2.cvtColor(processed, cv2.COLOR_RGB2GRAY) # Aplicar threshold adaptativo blur = cv2.GaussianBlur(gray, (5,5), 0) _, thresh = cv2.threshold(blur, 30, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Operações morfológicas kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)) morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) # Encontrar contornos contours, _ = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return None # Encontrar o contorno mais circular best_circularity = 0 best_contour = None for contour in contours: area = cv2.contourArea(contour) perimeter = cv2.arcLength(contour, True) if perimeter == 0: continue circularity = 4 * np.pi * area / (perimeter * perimeter) if circularity > best_circularity: best_circularity = circularity best_contour = contour if best_contour is None: return None (x, y), radius = cv2.minEnclosingCircle(best_contour) return (int(x), int(y), int(radius)) except Exception as e: logging.error(f"Erro na detecção da pupila: {str(e)}") return None def analyze_zone(self, img: np.ndarray, mask: np.ndarray, zone_name: str) -> Dict: """Análise detalhada de uma zona específica""" try: # Extrair características mean_color = cv2.mean(img, mask=mask) gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) zone_pixels = cv2.bitwise_and(gray, gray, mask=mask) if np.sum(mask) > 0: pixels = zone_pixels[mask > 0] mean_intensity = np.mean(pixels) std_dev = np.std(pixels) # Calcular características adicionais percentiles = np.percentile(pixels, [25, 50, 75]) # Gerar interpretação detalhada analysis = IrisAnalysis.get_zone_interpretation( zone_name, mean_intensity, std_dev ) # Adicionar métricas estatísticas analysis["metricas_detalhadas"] = { "mediana": float(percentiles[1]), "quartil_inferior": float(percentiles[0]), "quartil_superior": float(percentiles[2]), "pixels_analisados": len(pixels), "variacao_cor": { "r": mean_color[0], "g": mean_color[1], "b": mean_color[2] } } return analysis return {"erro": "Zona sem pixels válidos para análise"} except Exception as e: logging.error(f"Erro na análise da zona {zone_name}: {str(e)}") return {"erro": str(e)} def analyze_iris(self, img: np.ndarray) -> Tuple[np.ndarray, Dict]: """Análise principal com relatório detalhado""" try: output_img = img.copy() detailed_results = { "meta": { "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "versao_analise": "1.0.0" }, "resumo_geral": {}, "zonas": {}, "observacoes": [] } # Detectar pupila pupil = self.detect_pupil(img) if pupil is None: return img, {"erro": "Não foi possível detectar a pupila"} x, y, pupil_radius = pupil iris_radius = pupil_radius * 4 # Desenhar círculo da pupila cv2.circle(output_img, (x, y), pupil_radius, (0, 0, 0), 2) # Analisar cada zona overall_health_score = 0 num_zones = len(self.zones) for zone in self.zones: inner_r = int(iris_radius * zone.inner_ratio) outer_r = int(iris_radius * zone.outer_ratio) # Criar máscara para a zona mask = np.zeros(img.shape[:2], dtype=np.uint8) cv2.circle(mask, (x, y), outer_r, 255, -1) cv2.circle(mask, (x, y), inner_r, 0, -1) # Desenhar círculos da zona cv2.circle(output_img, (x, y), outer_r, zone.color, 2) # Analisar zona analysis = self.analyze_zone(img, mask, zone.name) detailed_results["zonas"][zone.name] = analysis # Calcular score geral if "metricas" in analysis: if analysis["metricas"]["nivel_geral"] == "alta": overall_health_score += 1 elif analysis["metricas"]["nivel_geral"] == "média": overall_health_score += 0.5 # Adicionar texto text_x = x - iris_radius text_y = y + outer_r cv2.putText(output_img, zone.name, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, zone.color, 1) # Calcular resumo geral health_percentage = (overall_health_score / num_zones) * 100 detailed_results["resumo_geral"] = { "indice_geral": f"{health_percentage:.1f}%", "interpretacao": "Bom" if health_percentage > 75 else "Moderado" if health_percentage > 50 else "Requer atenção" } return output_img, detailed_results except Exception as e: logging.error(f"Erro na análise da íris: {str(e)}") return img, {"erro": str(e)} def format_results(results: Dict) -> str: """Formata os resultados para exibição""" if "erro" in results: return f"Erro na análise: {results['erro']}" formatted = "# Relatório de Análise da Íris\n\n" # Adicionar resumo geral if "resumo_geral" in results: formatted += "## Resumo Geral\n" formatted += f"- Índice Geral: {results['resumo_geral']['indice_geral']}\n" formatted += f"- Interpretação: {results['resumo_geral']['interpretacao']}\n\n" # Adicionar análise por zona if "zonas" in results: formatted += "## Análise por Zona\n\n" for zone_name, analysis in results["zonas"].items(): formatted += f"### {zone_name}\n" formatted += f"- Aspectos Analisados: {analysis.get('aspectos_analisados', 'N/A')}\n" formatted += f"- Interpretação: {analysis.get('interpretacao', 'N/A')}\n" if "sugestoes" in analysis: formatted += "- Sugestões:\n" for sugestao in analysis["sugestoes"]: formatted += f" * {sugestao}\n" if "metricas" in analysis: formatted += f"- Nível Geral: {analysis['metricas']['nivel_geral']}\n" formatted += f"- Confiança da Análise: {analysis['metricas']['confianca_analise']}\n" formatted += "\n" # Adicionar timestamp if "meta" in results: formatted += f"\n---\nAnálise realizada em: {results['meta']['timestamp']}\n" formatted += f"Versão do sistema: {results['meta']['versao_analise']}\n" return formatted def process_image(img): """Função principal para processar imagem""" if img is None: return None, "Erro: Nenhuma imagem fornecida" analyzer = IrisAnalyzer() output_img, results = analyzer.analyze_iris(np.array(img)) formatted_results = format_results(results) return output_img, formatted_results # Interface Gradio with gr.Blocks(theme=gr.themes.Soft()) as iface: gr.Markdown(""" # 🔍 Analisador Avançado de Íris ### Sistema de análise baseado na teoria de Jensen ⚠️ **AVISO**: Esta é uma demonstração educacional. Não deve ser utilizada para diagnósticos médicos. """) with gr.Row(): with gr.Column(scale=1): input_image = gr.Image( label="Upload da imagem do olho", type="numpy", sources=["upload", "clipboard"] ) analyze_btn = gr.Button( "📸 Analisar Imagem", variant="primary" ) gr.Markdown(""" ### Instruções: 1. Faça upload de uma imagem clara do olho 2. Certifique-se que a íris está bem visível 3. Clique em "Analisar Imagem" 4. Revise o relatório detalhado """) with gr.Column(scale=1): output_image = gr.Image(label="Análise Visual") results_text = gr.Markdown(label="Relatório Detalhado") with gr.Row(): gr.Markdown(""" ### Legenda das Zonas: - 🔴 Zona Cerebral/Neural: Sistema nervoso - 🟢 Zona Digestiva: Sistema digestivo - 🔵 Zona Respiratória: Sistema respiratório - 🟡 Zona Circulatória: Sistema circulatório - 🟣 Zona Linfática: Sistema linfático - 🔰 Zona Endócrina: Sistema hormonal - ⚪ Zona Pupilar: Sistema nervoso autônomo """) analyze_btn.click( fn=process_image, inputs=input_image, outputs=[output_image, results_text] ) gr.Markdown(""" --- ### 📋 Sobre a Análise Este sistema realiza: - Detecção automática da pupila - Análise de 7 zonas principais da íris - Avaliação de padrões e texturas - Geração de relatório detalhado **Observações Importantes:** - A iridologia é uma prática alternativa - Os resultados são interpretativos - Consulte profissionais de saúde para diagnósticos --- """) # Configurações para execução if __name__ == "__main__": try: iface.launch() logging.info("Aplicação iniciada com sucesso") except Exception as e: logging.error(f"Erro ao iniciar a aplicação: {str(e)}") raise