ProyectoIntegrador39 commited on
Commit
bf9708e
·
verified ·
1 Parent(s): 92a1436

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +40 -12
app.py CHANGED
@@ -33,6 +33,7 @@ from astropy.io import fits
33
  from astropy.visualization import make_lupton_rgb
34
  from matplotlib.patches import Ellipse
35
 
 
36
  from galaxy_ellipse import measure_ellipse
37
 
38
  IMG_SIZE = 320
@@ -179,14 +180,20 @@ def predict_prob(rgb: np.ndarray, use_tta: bool) -> float:
179
 
180
  # --- Figure ---
181
 
182
- def render(rgb: np.ndarray, geo: dict):
183
- """Two-panel figure: enhanced RGB | enhanced RGB + ellipse overlay."""
 
 
 
 
 
 
184
  fig, axes = plt.subplots(1, 2, figsize=(8, 4.2))
185
- axes[0].imshow(rgb)
186
- axes[0].set_title("Imagen (Lupton grz)")
187
  axes[0].axis("off")
188
 
189
- axes[1].imshow(rgb)
190
  axes[1].set_title("Imagen + elipse")
191
  axes[1].axis("off")
192
  if geo.get("status") == "ok":
@@ -209,21 +216,23 @@ def render(rgb: np.ndarray, geo: dict):
209
 
210
  # --- Gradio callback ---
211
 
212
- def classify(text: str, layer: str, pixscale: float, use_tta: bool):
213
  try:
214
  ra, dec, label = resolve_coords(text)
215
  except Exception as exc:
216
- return None, f"No pude resolver la entrada: {exc}"
217
 
218
  try:
219
  rgb = fetch_rgb(ra, dec, layer, float(pixscale))
220
  except Exception as exc:
221
- return None, f"No pude bajar el cutout: {exc}"
222
 
 
 
223
  prob = predict_prob(rgb, use_tta)
224
  pred = int(prob >= THR)
225
  geo = measure_ellipse(rgb)
226
- fig = render(rgb, geo)
227
 
228
  ring_txt = (
229
  f"{geo['ring_radius']:.0f} px (candidato exploratorio)"
@@ -247,7 +256,14 @@ def classify(text: str, layer: str, pixscale: float, use_tta: bool):
247
  f"_La predicción es una sugerencia de apoyo, no la verdad. La elipse verde es el "
248
  f"ajuste de la galaxia; el anillo naranja punteado es un candidato exploratorio._"
249
  )
250
- return fig, summary
 
 
 
 
 
 
 
251
 
252
 
253
  EXAMPLES = [
@@ -264,6 +280,8 @@ with gr.Blocks(title="Anillos en galaxias — Legacy Survey") as demo:
264
  "**URL del visor** de Legacy Survey. Bajo el cutout grz, lo proceso igual que en "
265
  "el entrenamiento y corro el modelo (ConvNeXt-Base / Zoobot)."
266
  )
 
 
267
  with gr.Row():
268
  with gr.Column(scale=2):
269
  inp = gr.Textbox(label="Objeto / ra,dec / URL", placeholder="NGC 7796")
@@ -274,13 +292,23 @@ with gr.Blocks(title="Anillos en galaxias — Legacy Survey") as demo:
274
  pixscale = gr.Number(value=0.262, label="Pixscale (arcsec/px)")
275
  tta = gr.Checkbox(value=False, label="TTA (6 vistas, más lento y estable)")
276
  btn = gr.Button("Clasificar", variant="primary")
 
 
 
 
277
  gr.Examples(EXAMPLES, inputs=[inp])
278
  with gr.Column(scale=3):
279
  out_img = gr.Plot(label="Imagen + elipse")
280
  out_md = gr.Markdown()
281
 
282
- btn.click(classify, [inp, layer, pixscale, tta], [out_img, out_md])
283
- inp.submit(classify, [inp, layer, pixscale, tta], [out_img, out_md])
 
 
 
 
 
 
284
 
285
 
286
  if __name__ == "__main__":
 
33
  from astropy.visualization import make_lupton_rgb
34
  from matplotlib.patches import Ellipse
35
 
36
+ import enhance
37
  from galaxy_ellipse import measure_ellipse
38
 
39
  IMG_SIZE = 320
 
180
 
181
  # --- Figure ---
182
 
183
+ def render(rgb: np.ndarray, geo: dict, mode: str = "Original", gray: bool = False):
184
+ """Two-panel figure: enhanced RGB | enhanced RGB + ellipse overlay.
185
+
186
+ The enhancement is purely visual; the ellipse geometry was measured on the
187
+ original Lupton RGB, so it still lines up after any realce.
188
+ """
189
+ shown = enhance.apply(rgb, mode, gray)
190
+ title = "Imagen (Lupton grz)" if mode == "Original" else f"Imagen — {mode}"
191
  fig, axes = plt.subplots(1, 2, figsize=(8, 4.2))
192
+ axes[0].imshow(shown)
193
+ axes[0].set_title(title)
194
  axes[0].axis("off")
195
 
196
+ axes[1].imshow(shown)
197
  axes[1].set_title("Imagen + elipse")
198
  axes[1].axis("off")
199
  if geo.get("status") == "ok":
 
216
 
217
  # --- Gradio callback ---
218
 
219
+ def classify(text: str, layer: str, pixscale: float, use_tta: bool, mode: str, gray: bool):
220
  try:
221
  ra, dec, label = resolve_coords(text)
222
  except Exception as exc:
223
+ return None, f"No pude resolver la entrada: {exc}", None, None
224
 
225
  try:
226
  rgb = fetch_rgb(ra, dec, layer, float(pixscale))
227
  except Exception as exc:
228
+ return None, f"No pude bajar el cutout: {exc}", None, None
229
 
230
+ # Prediction and geometry use the ORIGINAL Lupton RGB; the realce is only
231
+ # for display and is re-applied (without re-running the model) on change.
232
  prob = predict_prob(rgb, use_tta)
233
  pred = int(prob >= THR)
234
  geo = measure_ellipse(rgb)
235
+ fig = render(rgb, geo, mode, gray)
236
 
237
  ring_txt = (
238
  f"{geo['ring_radius']:.0f} px (candidato exploratorio)"
 
256
  f"_La predicción es una sugerencia de apoyo, no la verdad. La elipse verde es el "
257
  f"ajuste de la galaxia; el anillo naranja punteado es un candidato exploratorio._"
258
  )
259
+ return fig, summary, rgb, geo
260
+
261
+
262
+ def rerender(rgb, geo, mode: str, gray: bool):
263
+ """Re-apply a realce to the already-fetched image (no model re-run)."""
264
+ if rgb is None or geo is None:
265
+ return None
266
+ return render(rgb, geo, mode, gray)
267
 
268
 
269
  EXAMPLES = [
 
280
  "**URL del visor** de Legacy Survey. Bajo el cutout grz, lo proceso igual que en "
281
  "el entrenamiento y corro el modelo (ConvNeXt-Base / Zoobot)."
282
  )
283
+ st_rgb = gr.State(None)
284
+ st_geo = gr.State(None)
285
  with gr.Row():
286
  with gr.Column(scale=2):
287
  inp = gr.Textbox(label="Objeto / ra,dec / URL", placeholder="NGC 7796")
 
292
  pixscale = gr.Number(value=0.262, label="Pixscale (arcsec/px)")
293
  tta = gr.Checkbox(value=False, label="TTA (6 vistas, más lento y estable)")
294
  btn = gr.Button("Clasificar", variant="primary")
295
+ mode = gr.Radio(
296
+ enhance.MODES, value="Original", label="Realce (visual, no afecta la predicción)"
297
+ )
298
+ gray = gr.Checkbox(value=False, label="Escala de grises (B/N)")
299
  gr.Examples(EXAMPLES, inputs=[inp])
300
  with gr.Column(scale=3):
301
  out_img = gr.Plot(label="Imagen + elipse")
302
  out_md = gr.Markdown()
303
 
304
+ inputs = [inp, layer, pixscale, tta, mode, gray]
305
+ outputs = [out_img, out_md, st_rgb, st_geo]
306
+ btn.click(classify, inputs, outputs)
307
+ inp.submit(classify, inputs, outputs)
308
+
309
+ # Changing the realce re-renders the already-fetched image instantly.
310
+ mode.change(rerender, [st_rgb, st_geo, mode, gray], out_img)
311
+ gray.change(rerender, [st_rgb, st_geo, mode, gray], out_img)
312
 
313
 
314
  if __name__ == "__main__":