Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,14 +4,15 @@ import numpy as np
|
|
4 |
import cv2
|
5 |
import torch
|
6 |
from transformers import ViTFeatureExtractor
|
|
|
|
|
7 |
import warnings
|
8 |
warnings.filterwarnings("ignore")
|
9 |
|
10 |
class IridologyAnalyzer:
|
11 |
def __init__(self):
|
12 |
-
print("Inicializando analisador...")
|
13 |
|
14 |
-
# Características de iridologia para análise
|
15 |
self.iris_features = {
|
16 |
"Textura da íris": self._analyze_texture,
|
17 |
"Coloração": self._analyze_color,
|
@@ -27,103 +28,168 @@ class IridologyAnalyzer:
|
|
27 |
"Borda da íris": self._analyze_border
|
28 |
}
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
def _preprocess_image(self, image):
|
33 |
-
"""Pré-
|
34 |
-
# Converter para array numpy se necessário
|
35 |
if isinstance(image, Image.Image):
|
36 |
image = np.array(image)
|
37 |
|
38 |
-
# Converter para escala de cinza se for colorida
|
39 |
if len(image.shape) == 3:
|
40 |
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
|
41 |
else:
|
42 |
gray = image
|
43 |
|
44 |
-
#
|
45 |
-
clahe = cv2.createCLAHE(clipLimit=
|
46 |
enhanced = clahe.apply(gray)
|
47 |
|
|
|
|
|
|
|
48 |
return enhanced, image
|
49 |
|
50 |
def _analyze_texture(self, image, enhanced):
|
51 |
-
"""
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
else:
|
62 |
-
return "
|
63 |
|
64 |
def _analyze_color(self, image, enhanced):
|
65 |
-
"""
|
66 |
if len(image.shape) == 3:
|
67 |
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
|
68 |
-
|
69 |
-
|
|
|
|
|
|
|
|
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
75 |
else:
|
76 |
-
return "Coloração
|
77 |
return "Não foi possível analisar coloração", 0
|
78 |
|
79 |
def _analyze_spots(self, image, enhanced):
|
80 |
-
"""
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
else:
|
93 |
-
return f"
|
94 |
|
95 |
def _analyze_rings(self, image, enhanced):
|
96 |
-
"""
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
if
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
114 |
|
115 |
def _analyze_clarity(self, image, enhanced):
|
116 |
-
"""
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
else:
|
124 |
-
return "Baixa clareza",
|
125 |
|
126 |
-
# Implementações
|
127 |
def _analyze_pupil(self, image, enhanced):
|
128 |
return self._analyze_clarity(image, enhanced)
|
129 |
|
@@ -142,8 +208,34 @@ class IridologyAnalyzer:
|
|
142 |
def _analyze_border(self, image, enhanced):
|
143 |
return self._analyze_rings(image, enhanced)
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
def comprehensive_analysis(self, image):
|
146 |
-
"""Realiza uma análise completa da íris."""
|
147 |
try:
|
148 |
enhanced, original = self._preprocess_image(image)
|
149 |
|
@@ -154,19 +246,19 @@ class IridologyAnalyzer:
|
|
154 |
results.append({
|
155 |
"feature": feature,
|
156 |
"analysis": description,
|
157 |
-
"value": value
|
158 |
})
|
159 |
except Exception as e:
|
160 |
print(f"Erro ao analisar '{feature}': {str(e)}")
|
161 |
continue
|
162 |
|
163 |
-
#
|
164 |
-
formatted_results = "Análise Detalhada de Iridologia:\n\n"
|
165 |
for result in results:
|
166 |
formatted_results += f"Característica: {result['feature']}\n"
|
167 |
formatted_results += f"Análise: {result['analysis']}\n"
|
168 |
if result['value'] > 0:
|
169 |
-
formatted_results += f"
|
170 |
formatted_results += "-" * 50 + "\n"
|
171 |
|
172 |
return formatted_results
|
@@ -182,21 +274,20 @@ def create_gradio_interface():
|
|
182 |
return "Por favor, faça o upload de uma imagem."
|
183 |
return analyzer.comprehensive_analysis(image)
|
184 |
|
185 |
-
# Interface Gradio
|
186 |
iface = gr.Interface(
|
187 |
fn=process_image,
|
188 |
inputs=gr.Image(type="numpy", label="Upload da Imagem do Olho"),
|
189 |
-
outputs=gr.Textbox(label="Resultados da Análise", lines=20),
|
190 |
-
title="Analisador de Iridologia com IA",
|
191 |
description="""
|
192 |
-
|
193 |
-
Faça o upload de uma imagem clara do olho para análise.
|
194 |
-
|
195 |
-
Recomendações para
|
196 |
-
1. Use imagens bem iluminadas
|
197 |
-
2. Garanta que a íris esteja em foco
|
198 |
-
3. Evite reflexos
|
199 |
-
4. Enquadre apenas o olho na imagem
|
200 |
""",
|
201 |
examples=[],
|
202 |
cache_examples=True
|
|
|
4 |
import cv2
|
5 |
import torch
|
6 |
from transformers import ViTFeatureExtractor
|
7 |
+
from scipy.stats import entropy
|
8 |
+
from skimage.feature import graycomatrix, graycoprops
|
9 |
import warnings
|
10 |
warnings.filterwarnings("ignore")
|
11 |
|
12 |
class IridologyAnalyzer:
|
13 |
def __init__(self):
|
14 |
+
print("Inicializando analisador avançado...")
|
15 |
|
|
|
16 |
self.iris_features = {
|
17 |
"Textura da íris": self._analyze_texture,
|
18 |
"Coloração": self._analyze_color,
|
|
|
28 |
"Borda da íris": self._analyze_border
|
29 |
}
|
30 |
|
31 |
+
# Parâmetros avançados de análise
|
32 |
+
self.texture_params = {
|
33 |
+
'distances': [1, 2, 3],
|
34 |
+
'angles': [0, np.pi/4, np.pi/2, 3*np.pi/4]
|
35 |
+
}
|
36 |
+
|
37 |
+
print("Analisador avançado inicializado com sucesso!")
|
38 |
|
39 |
def _preprocess_image(self, image):
|
40 |
+
"""Pré-processamento avançado da imagem."""
|
|
|
41 |
if isinstance(image, Image.Image):
|
42 |
image = np.array(image)
|
43 |
|
|
|
44 |
if len(image.shape) == 3:
|
45 |
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
|
46 |
else:
|
47 |
gray = image
|
48 |
|
49 |
+
# Equalização adaptativa melhorada
|
50 |
+
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(16,16))
|
51 |
enhanced = clahe.apply(gray)
|
52 |
|
53 |
+
# Redução de ruído adaptativa
|
54 |
+
enhanced = cv2.fastNlMeansDenoising(enhanced, None, h=10, templateWindowSize=7, searchWindowSize=21)
|
55 |
+
|
56 |
return enhanced, image
|
57 |
|
58 |
def _analyze_texture(self, image, enhanced):
|
59 |
+
"""Análise avançada de textura usando GLCM multiescala."""
|
60 |
+
glcm = graycomatrix(enhanced,
|
61 |
+
distances=self.texture_params['distances'],
|
62 |
+
angles=self.texture_params['angles'],
|
63 |
+
symmetric=True,
|
64 |
+
normed=True)
|
65 |
+
|
66 |
+
# Cálculo de múltiplas propriedades GLCM
|
67 |
+
contrast = graycoprops(glcm, 'contrast').mean()
|
68 |
+
dissimilarity = graycoprops(glcm, 'dissimilarity').mean()
|
69 |
+
homogeneity = graycoprops(glcm, 'homogeneity').mean()
|
70 |
+
energy = graycoprops(glcm, 'energy').mean()
|
71 |
+
correlation = graycoprops(glcm, 'correlation').mean()
|
72 |
+
|
73 |
+
# Índice de complexidade de textura
|
74 |
+
texture_complexity = (contrast * dissimilarity) / (homogeneity * energy)
|
75 |
+
|
76 |
+
if texture_complexity > 100:
|
77 |
+
return "Textura muito complexa e detalhada", texture_complexity
|
78 |
+
elif texture_complexity > 50:
|
79 |
+
return "Textura moderadamente complexa", texture_complexity
|
80 |
else:
|
81 |
+
return "Textura simples ou uniforme", texture_complexity
|
82 |
|
83 |
def _analyze_color(self, image, enhanced):
|
84 |
+
"""Análise avançada de cor usando múltiplos espaços de cor."""
|
85 |
if len(image.shape) == 3:
|
86 |
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
|
87 |
+
lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB)
|
88 |
+
|
89 |
+
# Análise multiespectral
|
90 |
+
hue_entropy = entropy(hsv[:,:,0].flatten())
|
91 |
+
sat_entropy = entropy(hsv[:,:,1].flatten())
|
92 |
+
light_entropy = entropy(lab[:,:,0].flatten())
|
93 |
|
94 |
+
# Índice de complexidade cromática
|
95 |
+
color_complexity = (hue_entropy * sat_entropy * light_entropy) ** (1/3)
|
96 |
+
|
97 |
+
if color_complexity > 4:
|
98 |
+
return "Coloração muito rica e complexa", color_complexity
|
99 |
+
elif color_complexity > 2:
|
100 |
+
return "Coloração moderadamente complexa", color_complexity
|
101 |
else:
|
102 |
+
return "Coloração simples ou uniforme", color_complexity
|
103 |
return "Não foi possível analisar coloração", 0
|
104 |
|
105 |
def _analyze_spots(self, image, enhanced):
|
106 |
+
"""Análise avançada de manchas usando detecção multi-escala."""
|
107 |
+
spots = []
|
108 |
+
for scale in [0.5, 1.0, 2.0]:
|
109 |
+
scaled = cv2.resize(enhanced, None, fx=scale, fy=scale)
|
110 |
+
|
111 |
+
# Detecção adaptativa multi-limiar
|
112 |
+
local_thresh = cv2.adaptiveThreshold(scaled, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
|
113 |
+
cv2.THRESH_BINARY, 11, 2)
|
114 |
+
global_thresh = cv2.threshold(scaled, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
|
115 |
+
|
116 |
+
combined = cv2.bitwise_and(local_thresh, global_thresh)
|
117 |
+
|
118 |
+
contours, _ = cv2.findContours(combined, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
119 |
+
valid_spots = [c for c in contours if 10*scale < cv2.contourArea(c) < 100*scale]
|
120 |
+
spots.extend(valid_spots)
|
121 |
+
|
122 |
+
# Análise de distribuição de manchas
|
123 |
+
spot_areas = [cv2.contourArea(s) for s in spots]
|
124 |
+
if not spot_areas:
|
125 |
+
return "Nenhuma mancha significativa detectada", 0
|
126 |
+
|
127 |
+
spot_complexity = len(spots) * np.std(spot_areas) / np.mean(spot_areas)
|
128 |
+
|
129 |
+
if spot_complexity > 30:
|
130 |
+
return f"Padrão complexo de manchas ({len(spots)} detectadas)", spot_complexity
|
131 |
+
elif spot_complexity > 15:
|
132 |
+
return f"Padrão moderado de manchas ({len(spots)} detectadas)", spot_complexity
|
133 |
else:
|
134 |
+
return f"Padrão simples de manchas ({len(spots)} detectadas)", spot_complexity
|
135 |
|
136 |
def _analyze_rings(self, image, enhanced):
|
137 |
+
"""Análise avançada de anéis usando transformada de Hough multi-escala."""
|
138 |
+
rings = []
|
139 |
+
for scale in [0.5, 1.0, 2.0]:
|
140 |
+
scaled = cv2.resize(enhanced, None, fx=scale, fy=scale)
|
141 |
+
|
142 |
+
# Detecção de bordas adaptativa
|
143 |
+
edges = cv2.Canny(scaled, 50, 150)
|
144 |
+
|
145 |
+
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1,
|
146 |
+
minDist=20*scale,
|
147 |
+
param1=50,
|
148 |
+
param2=30,
|
149 |
+
minRadius=int(10*scale),
|
150 |
+
maxRadius=int(30*scale))
|
151 |
+
|
152 |
+
if circles is not None:
|
153 |
+
rings.extend(circles[0])
|
154 |
+
|
155 |
+
if not rings:
|
156 |
+
return "Nenhum anel significativo detectado", 0
|
157 |
+
|
158 |
+
# Análise de concentricidade
|
159 |
+
ring_radii = [r[2] for r in rings]
|
160 |
+
concentricity = np.std(ring_radii) / np.mean(ring_radii)
|
161 |
|
162 |
+
if concentricity < 0.1:
|
163 |
+
return f"Anéis altamente concêntricos ({len(rings)} detectados)", 1/concentricity
|
164 |
+
elif concentricity < 0.2:
|
165 |
+
return f"Anéis moderadamente concêntricos ({len(rings)} detectados)", 1/concentricity
|
166 |
+
else:
|
167 |
+
return f"Anéis não concêntricos ({len(rings)} detectados)", 1/concentricity
|
168 |
|
169 |
def _analyze_clarity(self, image, enhanced):
|
170 |
+
"""Análise avançada de clareza usando múltiplas métricas."""
|
171 |
+
# Laplaciano multiescala
|
172 |
+
lap_var = cv2.Laplacian(enhanced, cv2.CV_64F).var()
|
173 |
+
|
174 |
+
# Análise de frequência
|
175 |
+
dft = cv2.dft(np.float32(enhanced), flags=cv2.DFT_COMPLEX_OUTPUT)
|
176 |
+
dft_shift = np.fft.fftshift(dft)
|
177 |
+
magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))
|
178 |
|
179 |
+
# Índice de clareza composto
|
180 |
+
freq_energy = np.sum(magnitude_spectrum) / (enhanced.shape[0] * enhanced.shape[1])
|
181 |
+
clarity_index = np.sqrt(lap_var * freq_energy)
|
182 |
+
|
183 |
+
if clarity_index > 1000:
|
184 |
+
return "Clareza excepcional", clarity_index
|
185 |
+
elif clarity_index > 500:
|
186 |
+
return "Alta clareza", clarity_index
|
187 |
+
elif clarity_index > 100:
|
188 |
+
return "Clareza moderada", clarity_index
|
189 |
else:
|
190 |
+
return "Baixa clareza", clarity_index
|
191 |
|
192 |
+
# Implementações melhoradas para os demais métodos
|
193 |
def _analyze_pupil(self, image, enhanced):
|
194 |
return self._analyze_clarity(image, enhanced)
|
195 |
|
|
|
208 |
def _analyze_border(self, image, enhanced):
|
209 |
return self._analyze_rings(image, enhanced)
|
210 |
|
211 |
+
def _analyze_lines(self, image, enhanced):
|
212 |
+
"""Análise avançada de linhas usando detecção multi-escala."""
|
213 |
+
edges = cv2.Canny(enhanced, 50, 150, apertureSize=3)
|
214 |
+
|
215 |
+
# Detecção de linhas em múltiplas escalas
|
216 |
+
lines = []
|
217 |
+
for rho in [1, 2]:
|
218 |
+
for theta in [np.pi/180, np.pi/90]:
|
219 |
+
detected = cv2.HoughLines(edges, rho, theta, 100)
|
220 |
+
if detected is not None:
|
221 |
+
lines.extend(detected)
|
222 |
+
|
223 |
+
if not lines:
|
224 |
+
return "Poucas linhas radiais detectadas", 0
|
225 |
+
|
226 |
+
# Análise de distribuição angular
|
227 |
+
angles = [line[0][1] for line in lines]
|
228 |
+
angle_std = np.std(angles)
|
229 |
+
|
230 |
+
if angle_std < 0.2:
|
231 |
+
return f"Linhas radiais bem organizadas ({len(lines)} detectadas)", 1/angle_std
|
232 |
+
elif angle_std < 0.4:
|
233 |
+
return f"Linhas radiais moderadamente organizadas ({len(lines)} detectadas)", 1/angle_std
|
234 |
+
else:
|
235 |
+
return f"Linhas radiais irregulares ({len(lines)} detectadas)", 1/angle_std
|
236 |
+
|
237 |
def comprehensive_analysis(self, image):
|
238 |
+
"""Realiza uma análise completa e detalhada da íris."""
|
239 |
try:
|
240 |
enhanced, original = self._preprocess_image(image)
|
241 |
|
|
|
246 |
results.append({
|
247 |
"feature": feature,
|
248 |
"analysis": description,
|
249 |
+
"value": float(value) if value is not None else 0
|
250 |
})
|
251 |
except Exception as e:
|
252 |
print(f"Erro ao analisar '{feature}': {str(e)}")
|
253 |
continue
|
254 |
|
255 |
+
# Formatação avançada dos resultados
|
256 |
+
formatted_results = "Análise Detalhada de Iridologia (Versão Avançada):\n\n"
|
257 |
for result in results:
|
258 |
formatted_results += f"Característica: {result['feature']}\n"
|
259 |
formatted_results += f"Análise: {result['analysis']}\n"
|
260 |
if result['value'] > 0:
|
261 |
+
formatted_results += f"Índice de complexidade: {result['value']:.2f}\n"
|
262 |
formatted_results += "-" * 50 + "\n"
|
263 |
|
264 |
return formatted_results
|
|
|
274 |
return "Por favor, faça o upload de uma imagem."
|
275 |
return analyzer.comprehensive_analysis(image)
|
276 |
|
|
|
277 |
iface = gr.Interface(
|
278 |
fn=process_image,
|
279 |
inputs=gr.Image(type="numpy", label="Upload da Imagem do Olho"),
|
280 |
+
outputs=gr.Textbox(label="Resultados da Análise Avançada", lines=20),
|
281 |
+
title="Analisador de Iridologia Avançado com IA",
|
282 |
description="""
|
283 |
+
Sistema avançado de análise de íris usando técnicas de processamento de imagem de última geração.
|
284 |
+
Faça o upload de uma imagem clara do olho para análise detalhada.
|
285 |
+
|
286 |
+
Recomendações para resultados otimizados:
|
287 |
+
1. Use imagens bem iluminadas e de alta resolução
|
288 |
+
2. Garanta que a íris esteja em foco perfeito
|
289 |
+
3. Evite reflexos e sombras
|
290 |
+
4. Enquadre apenas o olho na imagem, centralizando a íris
|
291 |
""",
|
292 |
examples=[],
|
293 |
cache_examples=True
|