Spaces:
Sleeping
Sleeping
import gradio as gr | |
import cv2 | |
import numpy as np | |
from PIL import Image | |
import io | |
from collections import defaultdict | |
def melhorar_contraste(imagem): | |
""" | |
Aplica equalização de histograma adaptativo para melhorar contraste | |
""" | |
lab = cv2.cvtColor(imagem, cv2.COLOR_RGB2LAB) | |
l, a, b = cv2.split(lab) | |
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8)) | |
l = clahe.apply(l) | |
lab = cv2.merge((l,a,b)) | |
return cv2.cvtColor(lab, cv2.COLOR_LAB2RGB) | |
def detectar_pupila_iris(imagem): | |
""" | |
Detecta pupila e íris com técnicas avançadas | |
""" | |
# Melhorar contraste | |
imagem_melhorada = melhorar_contraste(imagem) | |
# Converter para escala de cinza | |
gray = cv2.cvtColor(imagem_melhorada, cv2.COLOR_RGB2GRAY) | |
# Aplicar blur para reduzir ruído | |
blur = cv2.GaussianBlur(gray, (7, 7), 0) | |
# Detectar bordas | |
edges = cv2.Canny(blur, 30, 60) | |
# Aplicar fechamento morfológico para conectar bordas | |
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)) | |
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) | |
# Detectar círculos para pupila (menores) | |
pupila_circles = cv2.HoughCircles( | |
closed, | |
cv2.HOUGH_GRADIENT, | |
dp=1, | |
minDist=50, | |
param1=50, | |
param2=25, | |
minRadius=20, | |
maxRadius=50 | |
) | |
# Detectar círculos para íris (maiores) | |
iris_circles = cv2.HoughCircles( | |
closed, | |
cv2.HOUGH_GRADIENT, | |
dp=1, | |
minDist=100, | |
param1=50, | |
param2=30, | |
minRadius=80, | |
maxRadius=150 | |
) | |
output_img = imagem.copy() | |
# Desenhar círculos da pupila | |
if pupila_circles is not None: | |
pupila_circles = np.uint16(np.around(pupila_circles)) | |
for i in pupila_circles[0,:]: | |
# Desenhar círculo da pupila | |
cv2.circle(output_img, (i[0], i[1]), i[2], (255, 0, 0), 2) | |
# Desenhar centro | |
cv2.circle(output_img, (i[0], i[1]), 2, (0, 0, 255), 3) | |
pupila_info = (i[0], i[1], i[2]) | |
else: | |
pupila_info = None | |
# Desenhar círculos da íris | |
if iris_circles is not None: | |
iris_circles = np.uint16(np.around(iris_circles)) | |
for i in iris_circles[0,:]: | |
# Desenhar círculo da íris | |
cv2.circle(output_img, (i[0], i[1]), i[2], (0, 255, 0), 2) | |
iris_info = (i[0], i[1], i[2]) | |
# Desenhar setores da íris | |
ang_step = 45 | |
for ang in range(0, 360, ang_step): | |
end_x = int(i[0] + i[2] * np.cos(np.radians(ang))) | |
end_y = int(i[1] + i[2] * np.sin(np.radians(ang))) | |
cv2.line(output_img, (i[0], i[1]), (end_x, end_y), (0, 255, 0), 1) | |
else: | |
iris_info = None | |
return output_img, pupila_info, iris_info | |
def extrair_caracteristicas_avancadas(imagem, pupila_info, iris_info): | |
""" | |
Extrai características avançadas da íris usando a posição da pupila | |
""" | |
if pupila_info is None or iris_info is None: | |
return {} | |
# Converter para escala de cinza | |
gray = cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY) | |
# Coordenadas da pupila e íris | |
px, py, pr = pupila_info | |
ix, iy, ir = iris_info | |
# Criar máscara anelar (região entre pupila e íris) | |
mask = np.zeros_like(gray) | |
cv2.circle(mask, (ix, iy), ir, 255, -1) # Íris | |
cv2.circle(mask, (px, py), pr, 0, -1) # Pupila | |
# Aplicar máscara | |
iris_ring = cv2.bitwise_and(gray, gray, mask=mask) | |
# Análise de textura | |
caracteristicas = {} | |
# Divisão em setores | |
setores = { | |
"superior": (315, 45), | |
"direito": (45, 135), | |
"inferior": (135, 225), | |
"esquerdo": (225, 315) | |
} | |
for setor, (ang_inicio, ang_fim) in setores.items(): | |
# Criar máscara do setor | |
setor_mask = np.zeros_like(gray) | |
cv2.ellipse(setor_mask, | |
(ix, iy), | |
(ir, ir), | |
0, | |
ang_inicio, | |
ang_fim, | |
255, | |
-1) | |
# Aplicar máscara do setor | |
setor_roi = cv2.bitwise_and(iris_ring, iris_ring, mask=setor_mask) | |
# Análises no setor | |
non_zero = setor_roi[setor_roi != 0] | |
if len(non_zero) > 0: | |
caracteristicas[setor] = { | |
"media": np.mean(non_zero), | |
"std": np.std(non_zero), | |
"min": np.min(non_zero), | |
"max": np.max(non_zero) | |
} | |
return caracteristicas | |
def analisar_padrao_collarette(imagem, pupila_info, iris_info): | |
""" | |
Analisa o padrão do collarette (anel ao redor da pupila) | |
""" | |
if pupila_info is None or iris_info is None: | |
return None | |
px, py, pr = pupila_info | |
ix, iy, ir = iris_info | |
# Região do collarette (aprox. 1/3 da distância entre pupila e íris) | |
collarette_r = pr + int((ir - pr) * 0.33) | |
# Criar máscara anelar para o collarette | |
mask = np.zeros_like(cv2.cvtColor(imagem, cv2.COLOR_RGB2GRAY)) | |
cv2.circle(mask, (px, py), collarette_r, 255, -1) | |
cv2.circle(mask, (px, py), pr, 0, -1) | |
# Aplicar máscara | |
collarette = cv2.bitwise_and(imagem, imagem, mask=mask) | |
# Análise do collarette | |
gray_collarette = cv2.cvtColor(collarette, cv2.COLOR_RGB2GRAY) | |
non_zero = gray_collarette[gray_collarette != 0] | |
if len(non_zero) > 0: | |
return { | |
"intensidade_media": np.mean(non_zero), | |
"variacao": np.std(non_zero), | |
"regularidade": cv2.Laplacian(gray_collarette, cv2.CV_64F).var() | |
} | |
return None | |
def criar_interface(): | |
""" | |
Cria interface do Gradio com tema verde piscina | |
""" | |
theme = gr.themes.Soft( | |
primary_hue="teal", | |
secondary_hue="green", | |
).set( | |
body_text_color="#2A9D8F", | |
block_title_text_color="#264653", | |
block_label_text_color="#2A9D8F", | |
input_background_fill="#E9F5F3", | |
button_primary_background_fill="#2A9D8F", | |
button_primary_background_fill_dark="#264653", | |
) | |
def processar_imagem(imagem): | |
# Detectar pupila e íris | |
output_img, pupila_info, iris_info = detectar_pupila_iris(imagem) | |
if pupila_info is None or iris_info is None: | |
return output_img, "Não foi possível detectar pupila ou íris corretamente." | |
# Extrair características | |
caracteristicas = extrair_caracteristicas_avancadas(imagem, pupila_info, iris_info) | |
# Analisar collarette | |
collarette_info = analisar_padrao_collarette(imagem, pupila_info, iris_info) | |
# Gerar relatório | |
relatorio = "ANÁLISE IRIDOLÓGICA DETALHADA\n\n" | |
# Informações da pupila | |
px, py, pr = pupila_info | |
relatorio += f"Pupila:\n" | |
relatorio += f"- Centro: ({px}, {py})\n" | |
relatorio += f"- Raio: {pr}px\n" | |
# Informações da íris | |
ix, iy, ir = iris_info | |
relatorio += f"\nÍris:\n" | |
relatorio += f"- Centro: ({ix}, {iy})\n" | |
relatorio += f"- Raio: {ir}px\n" | |
# Análise por setores | |
relatorio += "\nAnálise por Setores:\n" | |
for setor, dados in caracteristicas.items(): | |
relatorio += f"\n{setor.title()}:\n" | |
relatorio += f"- Intensidade média: {dados['media']:.1f}\n" | |
relatorio += f"- Variação: {dados['std']:.1f}\n" | |
# Interpretar dados | |
if dados['std'] > 40: | |
relatorio += " * Alta variação - possível inflamação\n" | |
if dados['media'] < 100: | |
relatorio += " * Baixa intensidade - possível deficiência\n" | |
# Análise do collarette | |
if collarette_info: | |
relatorio += "\nAnálise do Collarette:\n" | |
if collarette_info['regularidade'] > 500: | |
relatorio += "- Irregularidade significativa\n" | |
if collarette_info['variacao'] > 30: | |
relatorio += "- Alta variação de textura\n" | |
return output_img, relatorio | |
# Interface | |
with gr.Blocks(theme=theme, title="Análise Iridológica Avançada") as interface: | |
gr.Markdown(""" | |
# Sistema Avançado de Análise Iridológica | |
### Detecção precisa de pupila e íris com análise setorial | |
""") | |
with gr.Tabs(): | |
# Aba de Análise | |
with gr.Tab("Análise de Imagem"): | |
with gr.Row(): | |
with gr.Column(): | |
input_image = gr.Image( | |
label="Imagem da Íris", | |
type="numpy" | |
) | |
with gr.Column(): | |
output_image = gr.Image( | |
label="Análise Visual" | |
) | |
analysis_btn = gr.Button("Analisar Íris", variant="primary") | |
output_text = gr.Textbox( | |
label="Relatório de Análise", | |
lines=15 | |
) | |
analysis_btn.click( | |
fn=processar_imagem, | |
inputs=[input_image], | |
outputs=[output_image, output_text] | |
) | |
# Aba de Informações | |
with gr.Tab("Guia de Captura"): | |
gr.Markdown(""" | |
## Guia para Captura de Imagem | |
### Requisitos da Imagem | |
1. **Iluminação** | |
- Luz uniforme | |
- Sem reflexos na pupila | |
- Sem sombras fortes | |
2. **Posicionamento** | |
- Olho bem aberto | |
- Íris centralizada | |
- Foco na íris | |
3. **Qualidade** | |
- Alta resolução | |
- Imagem nítida | |
- Sem borramento | |
### Dicas de Captura | |
- Use luz natural indireta | |
- Mantenha a câmera estável | |
- Capture múltiplas fotos | |
- Verifique o foco antes | |
""") | |
return interface | |
if __name__ == "__main__": | |
interface = criar_interface() | |
interface.launch(share=True) |