leonett commited on
Commit
6644d97
·
verified ·
1 Parent(s): 704bd9f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -22
app.py CHANGED
@@ -85,18 +85,22 @@ def analizar_manipulacion(imagen, metadatos):
85
  return manipulada, razones
86
 
87
 
 
88
  def realizar_ela(imagen):
89
- """Realiza ELA con parámetros automáticos optimizados y salida en BLANCO sobre fondo gris oscuro."""
90
  try:
 
91
  img_np = np.array(imagen.convert("RGB"))
92
  img_cv = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
93
 
94
- # Parámetros automáticos optimizados
95
- quality = 95
96
- scale = 47
97
- umbral = 25
98
-
99
- # Guardar y recargar con compresión
 
 
100
  temp_path = "/tmp/temp_image.jpg"
101
  cv2.imwrite(temp_path, img_cv, [cv2.IMWRITE_JPEG_QUALITY, quality])
102
  img_comprimida = cv2.imread(temp_path)
@@ -104,31 +108,42 @@ def realizar_ela(imagen):
104
  raise ValueError("Error al leer la imagen comprimida")
105
 
106
  # Calcular diferencia absoluta
107
- diferencia = cv2.absdiff(img_cv, img_comprimida)
108
- ela_imagen = scale * diferencia.astype(np.float32)
109
 
110
- # Normalizar y convertir a uint8
111
- ela_imagen = cv2.normalize(ela_imagen, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
112
- ela_imagen = cv2.GaussianBlur(ela_imagen, (3, 3), 0)
 
113
 
114
- # Convertir a escala de grises
115
- ela_gray = cv2.cvtColor(ela_imagen, cv2.COLOR_BGR2GRAY)
116
 
117
- # Crear máscara binaria
118
- _, mask = cv2.threshold(ela_gray, umbral, 255, cv2.THRESH_BINARY)
 
119
  mask = mask.astype(np.uint8)
120
 
121
- # ✅ ¡ESTO ES LO ÚNICO QUE CAMBIAMOS!
122
- # Áreas detectadas: BLANCO PURO
123
- ela_color = cv2.cvtColor(ela_gray, cv2.COLOR_GRAY2BGR) # Convertir gris BGR
124
- ela_color[mask > 0] = [255, 255, 255] # Blanco donde hay error
 
 
 
 
 
 
 
 
 
 
125
 
126
  # Fondo: imagen original en escala de grises oscurecida
127
  img_gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
128
  img_gray = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
129
- img_gray = cv2.convertScaleAbs(img_gray, alpha=0.5, beta=0)
130
 
131
- # Combinar: fondo gris + áreas blancas
132
  result = np.where(mask[..., None] > 0, ela_color, img_gray)
133
 
134
  os.remove(temp_path)
@@ -142,6 +157,9 @@ def realizar_ela(imagen):
142
 
143
 
144
 
 
 
 
145
  def procesar_imagen(archivo_imagen):
146
  """Procesa la imagen y devuelve ZIP + texto de análisis + imagen ELA + URL de Google Maps (si aplica)."""
147
  try:
 
85
  return manipulada, razones
86
 
87
 
88
+
89
  def realizar_ela(imagen):
90
+ """Realiza ELA con los parámetros y algoritmo exactos del código JavaScript, valores por defecto."""
91
  try:
92
+ # Convertir imagen a array numpy y a BGR para OpenCV
93
  img_np = np.array(imagen.convert("RGB"))
94
  img_cv = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
95
 
96
+ # Parámetros por defecto del código JS
97
+ quality = 95 # Calidad JPG (0-100)
98
+ noise_level = 3 # Amplitud del ruido (1-30)
99
+ error_scale = 57 / 100.0 # Escala de error (0-100 → 0.0-1.0)
100
+ brightness_pct = 100 # Brillo (0-150%)
101
+ equalize_histogram = False # Por defecto desactivado
102
+
103
+ # Guardar como JPG con calidad especificada
104
  temp_path = "/tmp/temp_image.jpg"
105
  cv2.imwrite(temp_path, img_cv, [cv2.IMWRITE_JPEG_QUALITY, quality])
106
  img_comprimida = cv2.imread(temp_path)
 
108
  raise ValueError("Error al leer la imagen comprimida")
109
 
110
  # Calcular diferencia absoluta
111
+ diferencia = cv2.absdiff(img_cv.astype(np.float32), img_comprimida.astype(np.float32))
 
112
 
113
+ # Aplicar "noiseLevel" y "errorScale" como en el código JS
114
+ # En JS: diff = Math.max(diffR, diffG, diffB) * errorScale * 20;
115
+ # Y cada canal se multiplica por (noiseLevel / 10)
116
+ scaled_diff = diferencia * (noise_level / 10.0) * error_scale * 20.0
117
 
118
+ # Limitar valores a 0-255 y convertir a uint8
119
+ scaled_diff = np.clip(scaled_diff, 0, 255).astype(np.uint8)
120
 
121
+ # Crear máscara: áreas con error significativo (simulando elaData.data[i + 3] > 0)
122
+ gray_diff = cv2.cvtColor(scaled_diff, cv2.COLOR_BGR2GRAY)
123
+ _, mask = cv2.threshold(gray_diff, 30, 255, cv2.THRESH_BINARY) # Umbral arbitrario para "diff > 0.3"
124
  mask = mask.astype(np.uint8)
125
 
126
+ # ✅ Aplicar ecualización de histograma si estuviera activada (aunque por defecto es False)
127
+ if equalize_histogram:
128
+ # Convertir a escala de grises, ecualizar, y volver a BGR
129
+ gray = cv2.cvtColor(scaled_diff, cv2.COLOR_BGR2GRAY)
130
+ gray_eq = cv2.equalizeHist(gray)
131
+ scaled_diff = cv2.cvtColor(gray_eq, cv2.COLOR_GRAY2BGR)
132
+
133
+ # ✅ Aplicar brillo (brightness)
134
+ brightness_factor = min(1.5, brightness_pct / 100.0)
135
+ scaled_diff = cv2.convertScaleAbs(scaled_diff, alpha=brightness_factor, beta=0)
136
+
137
+ # ✅ Crear imagen final: fondo negro, áreas detectadas en blanco/amarillo
138
+ # Convertimos la diferencia escalada a una imagen en color
139
+ ela_color = scaled_diff.copy()
140
 
141
  # Fondo: imagen original en escala de grises oscurecida
142
  img_gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
143
  img_gray = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
144
+ img_gray = cv2.convertScaleAbs(img_gray, alpha=0.5, beta=0) # Fondo oscuro
145
 
146
+ # Combinar: donde hay máscara, mostrar color; donde no, fondo gris
147
  result = np.where(mask[..., None] > 0, ela_color, img_gray)
148
 
149
  os.remove(temp_path)
 
157
 
158
 
159
 
160
+
161
+
162
+
163
  def procesar_imagen(archivo_imagen):
164
  """Procesa la imagen y devuelve ZIP + texto de análisis + imagen ELA + URL de Google Maps (si aplica)."""
165
  try: