DHEIVER commited on
Commit
5db4e41
·
verified ·
1 Parent(s): 2a24598

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -202
app.py CHANGED
@@ -1,222 +1,194 @@
1
  import gradio as gr
2
- from PIL import Image
3
- import numpy as np
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
- # [Previous initialization code remains the same...]
 
17
 
18
- def _preprocess_image(self, image):
19
- """Pré-processamento da imagem."""
20
- if isinstance(image, Image.Image):
21
- image = np.array(image)
 
22
 
23
- if len(image.shape) == 3:
24
- gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
25
- else:
26
- gray = image
27
-
28
- clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(16,16))
29
- enhanced = clahe.apply(gray)
30
- enhanced = cv2.fastNlMeansDenoising(enhanced, None, h=10, templateWindowSize=7, searchWindowSize=21)
31
 
32
- return enhanced, image
33
-
34
- def _analyze_texture(self, image, enhanced):
35
- """Análise de textura usando GLCM."""
36
- glcm = graycomatrix(enhanced,
37
- distances=[1, 2, 3],
38
- angles=[0, np.pi/4, np.pi/2, 3*np.pi/4],
39
- symmetric=True,
40
- normed=True)
41
-
42
- contrast = graycoprops(glcm, 'contrast').mean()
43
- dissimilarity = graycoprops(glcm, 'dissimilarity').mean()
44
- homogeneity = graycoprops(glcm, 'homogeneity').mean()
45
- energy = graycoprops(glcm, 'energy').mean()
46
- correlation = graycoprops(glcm, 'correlation').mean()
47
-
48
- texture_complexity = (contrast * dissimilarity) / (homogeneity * energy)
49
-
50
- if texture_complexity > 100:
51
- return "Textura muito complexa e detalhada", texture_complexity
52
- elif texture_complexity > 50:
53
- return "Textura moderadamente complexa", texture_complexity
54
- else:
55
- return "Textura simples ou uniforme", texture_complexity
56
-
57
- def _analyze_color(self, image, enhanced):
58
- """Análise de cor."""
59
- if len(image.shape) == 3:
60
- hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
61
- lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB)
62
-
63
- hue_entropy = entropy(hsv[:,:,0].flatten())
64
- sat_entropy = entropy(hsv[:,:,1].flatten())
65
- light_entropy = entropy(lab[:,:,0].flatten())
66
-
67
- color_complexity = (hue_entropy * sat_entropy * light_entropy) ** (1/3)
68
-
69
- if color_complexity > 4:
70
- return "Coloração muito rica e complexa", color_complexity
71
- elif color_complexity > 2:
72
- return "Coloração moderadamente complexa", color_complexity
73
- else:
74
- return "Coloração simples ou uniforme", color_complexity
75
- return "Não foi possível analisar coloração", 0
76
-
77
- def _analyze_spots(self, image, enhanced):
78
- """Análise de manchas."""
79
- spots = []
80
- for scale in [0.5, 1.0, 2.0]:
81
- scaled = cv2.resize(enhanced, None, fx=scale, fy=scale)
82
 
83
- local_thresh = cv2.adaptiveThreshold(scaled, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
84
- cv2.THRESH_BINARY, 11, 2)
85
- global_thresh = cv2.threshold(scaled, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
 
86
 
87
- combined = cv2.bitwise_and(local_thresh, global_thresh)
88
- contours, _ = cv2.findContours(combined, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
89
- valid_spots = [c for c in contours if 10*scale < cv2.contourArea(c) < 100*scale]
90
- spots.extend(valid_spots)
91
 
92
- if not spots:
93
- return "Nenhuma mancha significativa detectada", 0
94
 
95
- spot_complexity = len(spots) * np.std([cv2.contourArea(s) for s in spots])
96
-
97
- if spot_complexity > 1000:
98
- return f"Padrão complexo de manchas ({len(spots)} detectadas)", spot_complexity
99
- elif spot_complexity > 500:
100
- return f"Padrão moderado de manchas ({len(spots)} detectadas)", spot_complexity
 
 
 
 
 
 
 
 
 
 
 
101
  else:
102
- return f"Padrão simples de manchas ({len(spots)} detectadas)", spot_complexity
103
-
104
- def _analyze_rings(self, image, enhanced):
105
- """Análise de anéis."""
106
- circles = cv2.HoughCircles(enhanced, cv2.HOUGH_GRADIENT, 1,
107
- minDist=20,
108
- param1=50,
109
- param2=30,
110
- minRadius=10,
111
- maxRadius=30)
112
-
113
- if circles is None:
114
- return "Nenhum anel significativo detectado", 0
115
-
116
- circles = np.uint16(np.around(circles[0]))
117
- concentricity = np.std([c[2] for c in circles]) / np.mean([c[2] for c in circles])
118
-
119
- if concentricity < 0.1:
120
- return f"Anéis altamente concêntricos ({len(circles)} detectados)", 1/concentricity
121
- elif concentricity < 0.2:
122
- return f"Anéis moderadamente concêntricos ({len(circles)} detectados)", 1/concentricity
123
  else:
124
- return f"Anéis não concêntricos ({len(circles)} detectados)", 1/concentricity
125
-
126
- def _analyze_pupil(self, image, enhanced):
127
- """Análise da pupila."""
128
- return self._analyze_clarity(image, enhanced)
129
-
130
- def _analyze_lines(self, image, enhanced):
131
- """Análise de linhas."""
132
- edges = cv2.Canny(enhanced, 50, 150, apertureSize=3)
133
- lines = cv2.HoughLines(edges, 1, np.pi/180, 100)
 
 
 
 
 
 
 
134
 
135
- if lines is None:
136
- return "Poucas linhas radiais detectadas", 0
137
 
138
- angles = [line[0][1] for line in lines]
139
- angle_std = np.std(angles)
140
 
141
- if angle_std < 0.2:
142
- return f"Linhas radiais bem organizadas ({len(lines)} detectadas)", 1/angle_std
143
- elif angle_std < 0.4:
144
- return f"Linhas radiais moderadamente organizadas ({len(lines)} detectadas)", 1/angle_std
145
- else:
146
- return f"Linhas radiais irregulares ({len(lines)} detectadas)", 1/angle_std
147
-
148
- def _analyze_pigmentation(self, image, enhanced):
149
- """Análise de pigmentação."""
150
- return self._analyze_color(image, enhanced)
151
-
152
- def _analyze_clarity(self, image, enhanced):
153
- """Análise de clareza."""
154
- lap_var = cv2.Laplacian(enhanced, cv2.CV_64F).var()
155
- dft = cv2.dft(np.float32(enhanced), flags=cv2.DFT_COMPLEX_OUTPUT)
156
- dft_shift = np.fft.fftshift(dft)
157
- magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))
158
-
159
- freq_energy = np.sum(magnitude_spectrum) / (enhanced.shape[0] * enhanced.shape[1])
160
- clarity_index = np.sqrt(lap_var * freq_energy)
161
-
162
- if clarity_index > 1000:
163
- return "Clareza excepcional", clarity_index
164
- elif clarity_index > 500:
165
- return "Alta clareza", clarity_index
166
- elif clarity_index > 100:
167
- return "Clareza moderada", clarity_index
168
- else:
169
- return "Baixa clareza", clarity_index
170
-
171
- def _analyze_tissue(self, image, enhanced):
172
- """Análise do tecido."""
173
- return self._analyze_texture(image, enhanced)
174
-
175
- def _analyze_white_marks(self, image, enhanced):
176
- """Análise de marcas brancas."""
177
- return self._analyze_spots(image, enhanced)
178
-
179
- def _analyze_fibers(self, image, enhanced):
180
- """Análise de fibras."""
181
- return self._analyze_lines(image, enhanced)
182
-
183
- def _analyze_border(self, image, enhanced):
184
- """Análise da borda."""
185
- return self._analyze_rings(image, enhanced)
186
-
187
- # [Previous comprehensive_analysis method remains the same...]
188
-
189
- def create_gradio_interface():
190
- analyzer = IridologyAnalyzer()
191
-
192
- def process_image(image):
193
- if image is None:
194
- return "Por favor, faça o upload de uma imagem."
195
- return analyzer.comprehensive_analysis(image)
196
-
197
- iface = gr.Interface(
198
- fn=process_image,
199
- inputs=gr.Image(type="numpy", label="Upload da Imagem do Olho"),
200
- outputs=gr.Textbox(label="Resultados da Análise Avançada", lines=30),
201
- title="Analisador de Iridologia Avançado com IA",
202
- description="""
203
- Sistema avançado de análise de íris usando técnicas de processamento de imagem e correlações de saúde.
204
- Faça o upload de uma imagem clara do olho para análise detalhada.
205
-
206
- IMPORTANTE: Esta ferramenta é apenas para fins educativos e NÃO substitui diagnóstico médico profissional.
207
-
208
- Recomendações para resultados otimizados:
209
- 1. Use imagens bem iluminadas e de alta resolução
210
- 2. Garanta que a íris esteja em foco perfeito
211
- 3. Evite reflexos e sombras
212
- 4. Enquadre apenas o olho na imagem, centralizando a íris
213
- """,
214
- examples=[],
215
- cache_examples=True
216
- )
217
-
218
- return iface
219
 
220
  if __name__ == "__main__":
221
- iface = create_gradio_interface()
222
  iface.launch()
 
1
  import gradio as gr
 
 
2
  import cv2
3
+ import numpy as np
4
+ from PIL import Image
5
+ from dataclasses import dataclass
6
+ from typing import Tuple, Dict, List
7
  import torch
8
+ import torch.nn.functional as F
9
+ import torchvision.transforms as transforms
10
+
11
+ @dataclass
12
+ class IrisZone:
13
+ name: str
14
+ inner_ratio: float
15
+ outer_ratio: float
16
+ color: Tuple[int, int, int]
17
+ angle_start: float = 0
18
+ angle_end: float = 360
19
+
20
+ class IrisAnalyzer:
21
  def __init__(self):
22
+ # Define zonas com cores distintas e ângulos específicos
23
+ self.zones = [
24
+ IrisZone("Zona Cerebral/Neural", 0.85, 1.0, (255, 0, 0)),
25
+ IrisZone("Zona Digestiva", 0.7, 0.85, (0, 255, 0)),
26
+ IrisZone("Zona Respiratória", 0.55, 0.7, (0, 0, 255)),
27
+ IrisZone("Zona Circulatória", 0.4, 0.55, (255, 255, 0)),
28
+ IrisZone("Zona Linfática", 0.25, 0.4, (255, 0, 255)),
29
+ IrisZone("Zona Endócrina", 0.15, 0.25, (0, 255, 255)),
30
+ IrisZone("Zona Pupilar", 0, 0.15, (128, 128, 128))
31
+ ]
32
+
33
+ def preprocess_image(self, img: np.ndarray) -> np.ndarray:
34
+ """Pré-processa a imagem para melhorar a detecção"""
35
+ # Converter para escala de cinza
36
+ gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
37
+
38
+ # Aplicar equalização de histograma adaptativo
39
+ clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
40
+ enhanced = clahe.apply(gray)
41
 
42
+ # Redução de ruído
43
+ denoised = cv2.fastNlMeansDenoising(enhanced)
44
 
45
+ return denoised
46
+
47
+ def detect_pupil(self, img: np.ndarray) -> Tuple[int, int, int]:
48
+ """Detecta a pupila usando técnicas avançadas"""
49
+ preprocessed = self.preprocess_image(img)
50
 
51
+ # Threshold adaptativo
52
+ _, thresh = cv2.threshold(preprocessed, 30, 255,
53
+ cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
 
 
 
 
 
54
 
55
+ # Operações morfológicas
56
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
57
+ morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
58
+
59
+ # Encontrar contornos
60
+ contours, _ = cv2.findContours(morph, cv2.RETR_EXTERNAL,
61
+ cv2.CHAIN_APPROX_SIMPLE)
62
+
63
+ if not contours:
64
+ return None
65
+
66
+ # Encontrar o contorno mais circular
67
+ max_circularity = 0
68
+ best_contour = None
69
+
70
+ for contour in contours:
71
+ area = cv2.contourArea(contour)
72
+ perimeter = cv2.arcLength(contour, True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
+ if perimeter == 0:
75
+ continue
76
+
77
+ circularity = 4 * np.pi * area / (perimeter * perimeter)
78
 
79
+ if circularity > max_circularity:
80
+ max_circularity = circularity
81
+ best_contour = contour
 
82
 
83
+ if best_contour is None:
84
+ return None
85
 
86
+ # Ajustar círculo
87
+ (x, y), radius = cv2.minEnclosingCircle(best_contour)
88
+ return (int(x), int(y), int(radius))
89
+
90
+ def analyze_zone(self, img: np.ndarray, mask: np.ndarray) -> Dict:
91
+ """Analisa características da zona usando a máscara"""
92
+ # Extrair características da região
93
+ mean_color = cv2.mean(img, mask=mask)
94
+
95
+ # Calcular textura usando GLCM
96
+ gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
97
+ zone_pixels = cv2.bitwise_and(gray, gray, mask=mask)
98
+
99
+ # Análise de textura básica
100
+ if np.sum(mask) > 0:
101
+ std_dev = np.std(zone_pixels[mask > 0])
102
+ mean_intensity = np.mean(zone_pixels[mask > 0])
103
  else:
104
+ std_dev = 0
105
+ mean_intensity = 0
106
+
107
+ return {
108
+ 'mean_intensity': mean_intensity,
109
+ 'std_dev': std_dev,
110
+ 'color_variation': mean_color[:3]
111
+ }
112
+
113
+ def interpret_zone(self, analysis: Dict) -> str:
114
+ """Interpreta os resultados da análise"""
115
+ intensity = analysis['mean_intensity']
116
+ variation = analysis['std_dev']
117
+
118
+ if intensity < 85:
119
+ base_condition = "Possível área de atenção"
120
+ elif intensity < 170:
121
+ base_condition = "Área moderada"
 
 
 
122
  else:
123
+ base_condition = "Área normal"
124
+
125
+ detail = f"(Intensidade: {intensity:.1f}, Variação: {variation:.1f})"
126
+ return f"{base_condition} {detail}"
127
+
128
+ def analyze_iris(self, img: np.ndarray) -> Tuple[np.ndarray, Dict]:
129
+ """Análise principal da íris"""
130
+ # Criar cópia para desenho
131
+ output_img = img.copy()
132
+ results = {}
133
+
134
+ # Detectar pupila
135
+ pupil = self.detect_pupil(img)
136
+ if pupil is None:
137
+ return img, {"Erro": "Não foi possível detectar a pupila"}
138
+
139
+ x, y, pupil_radius = pupil
140
 
141
+ # Estimar raio da íris (aproximadamente 4x o raio da pupila)
142
+ iris_radius = pupil_radius * 4
143
 
144
+ # Desenhar círculo da pupila
145
+ cv2.circle(output_img, (x, y), pupil_radius, (0, 0, 0), 2)
146
 
147
+ # Analisar cada zona
148
+ for zone in self.zones:
149
+ inner_r = int(iris_radius * zone.inner_ratio)
150
+ outer_r = int(iris_radius * zone.outer_ratio)
151
+
152
+ # Criar máscara para a zona
153
+ mask = np.zeros(img.shape[:2], dtype=np.uint8)
154
+ cv2.circle(mask, (x, y), outer_r, 255, -1)
155
+ cv2.circle(mask, (x, y), inner_r, 0, -1)
156
+
157
+ # Desenhar círculos da zona
158
+ cv2.circle(output_img, (x, y), outer_r, zone.color, 2)
159
+
160
+ # Analisar zona
161
+ analysis = self.analyze_zone(img, mask)
162
+ interpretation = self.interpret_zone(analysis)
163
+ results[zone.name] = interpretation
164
+
165
+ # Adicionar texto
166
+ text_x = x - iris_radius
167
+ text_y = y + outer_r
168
+ cv2.putText(output_img, zone.name, (text_x, text_y),
169
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, zone.color, 1)
170
+
171
+ return output_img, results
172
+
173
+ def process_image(img):
174
+ analyzer = IrisAnalyzer()
175
+ return analyzer.analyze_iris(np.array(img))
176
+
177
+ # Interface Gradio
178
+ iface = gr.Interface(
179
+ fn=process_image,
180
+ inputs=gr.Image(),
181
+ outputs=[
182
+ gr.Image(label="Análise Visual"),
183
+ gr.JSON(label="Resultados da Análise por Zona")
184
+ ],
185
+ title="Analisador Avançado de Íris (Baseado na Teoria de Jensen)",
186
+ description="""AVISO: Esta é uma demonstração educacional baseada na teoria de iridologia.
187
+ Esta não é uma ferramenta diagnóstica validada cientificamente e não deve ser usada para
188
+ decisões médicas. Consulte sempre um profissional de saúde qualificado para diagnósticos.""",
189
+ examples=[],
190
+ theme="default"
191
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  if __name__ == "__main__":
 
194
  iface.launch()