DHEIVER's picture
Update app.py
5db4e41 verified
raw
history blame
6.87 kB
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()