Spaces:
Sleeping
Sleeping
File size: 6,872 Bytes
7b945e6 78b9561 5db4e41 7b945e6 5db4e41 7b945e6 5db4e41 7b945e6 5db4e41 2a24598 5db4e41 2a24598 5db4e41 2a24598 5db4e41 bd95651 5db4e41 bd95651 5db4e41 2a24598 5db4e41 78b9561 5db4e41 2a24598 5db4e41 2a24598 5db4e41 2a24598 5db4e41 2a24598 5db4e41 2a24598 5db4e41 7b945e6 e1d98e8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
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
@dataclass
class IrisZone:
name: str
inner_ratio: float
outer_ratio: float
color: Tuple[int, int, int]
angle_start: float = 0
angle_end: float = 360
class IrisAnalyzer:
def __init__(self):
# Define zonas com cores distintas e ângulos específicos
self.zones = [
IrisZone("Zona Cerebral/Neural", 0.85, 1.0, (255, 0, 0)),
IrisZone("Zona Digestiva", 0.7, 0.85, (0, 255, 0)),
IrisZone("Zona Respiratória", 0.55, 0.7, (0, 0, 255)),
IrisZone("Zona Circulatória", 0.4, 0.55, (255, 255, 0)),
IrisZone("Zona Linfática", 0.25, 0.4, (255, 0, 255)),
IrisZone("Zona Endócrina", 0.15, 0.25, (0, 255, 255)),
IrisZone("Zona Pupilar", 0, 0.15, (128, 128, 128))
]
def preprocess_image(self, img: np.ndarray) -> np.ndarray:
"""Pré-processa a imagem para melhorar a detecção"""
# Converter para escala de cinza
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# Aplicar equalização de histograma adaptativo
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
enhanced = clahe.apply(gray)
# Redução de ruído
denoised = cv2.fastNlMeansDenoising(enhanced)
return denoised
def detect_pupil(self, img: np.ndarray) -> Tuple[int, int, int]:
"""Detecta a pupila usando técnicas avançadas"""
preprocessed = self.preprocess_image(img)
# Threshold adaptativo
_, thresh = cv2.threshold(preprocessed, 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
max_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 > max_circularity:
max_circularity = circularity
best_contour = contour
if best_contour is None:
return None
# Ajustar círculo
(x, y), radius = cv2.minEnclosingCircle(best_contour)
return (int(x), int(y), int(radius))
def analyze_zone(self, img: np.ndarray, mask: np.ndarray) -> Dict:
"""Analisa características da zona usando a máscara"""
# Extrair características da região
mean_color = cv2.mean(img, mask=mask)
# Calcular textura usando GLCM
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
zone_pixels = cv2.bitwise_and(gray, gray, mask=mask)
# Análise de textura básica
if np.sum(mask) > 0:
std_dev = np.std(zone_pixels[mask > 0])
mean_intensity = np.mean(zone_pixels[mask > 0])
else:
std_dev = 0
mean_intensity = 0
return {
'mean_intensity': mean_intensity,
'std_dev': std_dev,
'color_variation': mean_color[:3]
}
def interpret_zone(self, analysis: Dict) -> str:
"""Interpreta os resultados da análise"""
intensity = analysis['mean_intensity']
variation = analysis['std_dev']
if intensity < 85:
base_condition = "Possível área de atenção"
elif intensity < 170:
base_condition = "Área moderada"
else:
base_condition = "Área normal"
detail = f"(Intensidade: {intensity:.1f}, Variação: {variation:.1f})"
return f"{base_condition} {detail}"
def analyze_iris(self, img: np.ndarray) -> Tuple[np.ndarray, Dict]:
"""Análise principal da íris"""
# Criar cópia para desenho
output_img = img.copy()
results = {}
# 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
# Estimar raio da íris (aproximadamente 4x o raio da pupila)
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
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)
interpretation = self.interpret_zone(analysis)
results[zone.name] = interpretation
# 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)
return output_img, results
def process_image(img):
analyzer = IrisAnalyzer()
return analyzer.analyze_iris(np.array(img))
# Interface Gradio
iface = gr.Interface(
fn=process_image,
inputs=gr.Image(),
outputs=[
gr.Image(label="Análise Visual"),
gr.JSON(label="Resultados da Análise por Zona")
],
title="Analisador Avançado de Íris (Baseado na Teoria de Jensen)",
description="""AVISO: Esta é uma demonstração educacional baseada na teoria de iridologia.
Esta não é uma ferramenta diagnóstica validada cientificamente e não deve ser usada para
decisões médicas. Consulte sempre um profissional de saúde qualificado para diagnósticos.""",
examples=[],
theme="default"
)
if __name__ == "__main__":
iface.launch() |