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