usingcolor commited on
Commit
df9d184
·
1 Parent(s): ef0824d

chore: initialize git repository and update project configuration files

Browse files
Files changed (1) hide show
  1. app.py +11 -109
app.py CHANGED
@@ -61,100 +61,15 @@ MODEL_FILENAME = "mambaeye_base_ft.pt"
61
  _GLOBAL_MODEL = None
62
 
63
 
64
- # --- HOVER SCRIPT INJECTION ---
65
- JS_HOVER_SCRIPT = """
66
- function() {
67
- let overlay = document.getElementById('mamba-hover-overlay');
68
- if (!overlay) {
69
- overlay = document.createElement('div');
70
- overlay.id = 'mamba-hover-overlay';
71
- overlay.style.position = 'fixed';
72
- overlay.style.pointerEvents = 'none';
73
- overlay.style.border = '2px solid rgba(0, 102, 255, 0.8)';
74
- overlay.style.backgroundColor = 'rgba(0, 102, 255, 0.2)';
75
- overlay.style.zIndex = '99999';
76
- overlay.style.display = 'none';
77
- document.body.appendChild(overlay);
78
- }
79
-
80
- document.addEventListener('mousemove', (e) => {
81
- let imgs = document.querySelectorAll('img');
82
- let targetImg = null;
83
- for (let img of imgs) {
84
- if (img.closest('.gradio-image-hook')) {
85
- if (img.src && !img.src.includes('data:image/svg')) {
86
- targetImg = img;
87
- }
88
- }
89
- }
90
- if (!targetImg) { overlay.style.display = 'none'; return; }
91
-
92
- let rect = targetImg.getBoundingClientRect();
93
- if (e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom) {
94
- let nw = targetImg.naturalWidth;
95
- let nh = targetImg.naturalHeight;
96
- if (nw === 0 || nh === 0) return;
97
-
98
- let cw = rect.width;
99
- let ch = rect.height;
100
- let imgRatio = nw / nh;
101
- let containerRatio = cw / ch;
102
-
103
- let renderW, renderH, renderX, renderY;
104
- if (imgRatio > containerRatio) {
105
- renderW = cw;
106
- renderH = cw / imgRatio;
107
- renderX = 0;
108
- renderY = (ch - renderH) / 2;
109
- } else {
110
- renderH = ch;
111
- renderW = ch * imgRatio;
112
- renderY = 0;
113
- renderX = (cw - renderW) / 2;
114
- }
115
-
116
- let relX = e.clientX - rect.left - renderX;
117
- let relY = e.clientY - rect.top - renderY;
118
-
119
- if (relX >= 0 && relX <= renderW && relY >= 0 && relY <= renderH) {
120
- let scale = renderW / nw;
121
- let TARGET_CANVAS_SIZE = 512;
122
- let ratio = Math.min(TARGET_CANVAS_SIZE / nw, TARGET_CANVAS_SIZE / nh);
123
-
124
- let origX = relX / scale;
125
- let origY = relY / scale;
126
-
127
- let y_offset = (TARGET_CANVAS_SIZE - nw * ratio) / 2;
128
- let x_offset = (TARGET_CANVAS_SIZE - nh * ratio) / 2;
129
-
130
- let canvas_y = origX * ratio + y_offset;
131
- let canvas_x = origY * ratio + x_offset;
132
-
133
- let px = Math.floor(canvas_x / 16) * 16;
134
- let py = Math.floor(canvas_y / 16) * 16;
135
-
136
- let start_orig_y = (py - y_offset) / ratio;
137
- let start_orig_x = (px - x_offset) / ratio;
138
-
139
- let render_box_x = rect.left + renderX + start_orig_y * scale;
140
- let render_box_y = rect.top + renderY + start_orig_x * scale;
141
-
142
- let size_scale = (16 / ratio) * scale;
143
-
144
- overlay.style.left = render_box_x + "px";
145
- overlay.style.top = render_box_y + "px";
146
- overlay.style.width = size_scale + "px";
147
- overlay.style.height = size_scale + "px";
148
- overlay.style.display = 'block';
149
- } else {
150
- overlay.style.display = 'none';
151
- }
152
- } else {
153
- overlay.style.display = 'none';
154
- }
155
- });
156
  }
157
  """
 
158
  # -----------------------------
159
 
160
  def get_model():
@@ -258,18 +173,6 @@ def draw_patches_on_image(image_arr, positions, x_offset, y_offset, h, w):
258
  # Paste original color into the highlighted region
259
  patch_crop = orig_pil.crop(box)
260
  temp_img.paste(patch_crop, box)
261
-
262
- color = "red" if i == len(positions) - 1 else "blue"
263
- draw.rectangle(box, outline=color, width=2)
264
-
265
- if i > 0:
266
- prev_py, prev_px = positions[i-1]
267
- prev_y = (prev_py - y_offset) / ratio
268
- prev_x = (prev_px - x_offset) / ratio
269
-
270
- center_prev = (prev_y + orig_px_size / 2, prev_x + orig_px_size / 2)
271
- center_curr = (orig_y + orig_px_size / 2, orig_x + orig_px_size / 2)
272
- draw.line([center_prev, center_curr], fill="blue", width=2)
273
 
274
  return np.array(temp_img), positions
275
 
@@ -366,8 +269,9 @@ def process_click_inference(x_orig, y_orig, original_image, state):
366
  canvas_y = int(x_orig * ratio) + state['y_offset']
367
  canvas_x = int(y_orig * ratio) + state['x_offset']
368
 
369
- px = (canvas_x // PATCH_SIZE) * PATCH_SIZE
370
- py = (canvas_y // PATCH_SIZE) * PATCH_SIZE
 
371
 
372
  cur_loc = state['cur_location'].to(device) if state['cur_location'] is not None else None
373
  loc_tensor = torch.tensor([[px, py]], dtype=torch.long, device=device)
@@ -419,7 +323,7 @@ def on_clear(original_image):
419
 
420
  return grey_base_np, {"Cleared": 1.0}, init_state_for_image(original_image), "Selections cleared. Ready for new patch sequence."
421
 
422
- with gr.Blocks(title="MambaEye Interactive Demo") as demo:
423
  gr.Markdown("# MambaEye Interactive Inference Demo")
424
  gr.Markdown("This interface incorporates the full **MambaEye-base** model natively.")
425
 
@@ -471,7 +375,5 @@ with gr.Blocks(title="MambaEye Interactive Demo") as demo:
471
  outputs=[input_image, model_output_label, state, status_text]
472
  )
473
 
474
- demo.load(js=JS_HOVER_SCRIPT)
475
-
476
  if __name__ == "__main__":
477
  demo.launch(theme=gr.themes.Soft(), ssr_mode=False)
 
61
  _GLOBAL_MODEL = None
62
 
63
 
64
+ # --- FALLBACK CSS INJECTION ---
65
+ # We use a CSS override to display a precision crosshair since custom dynamic HTML div overlays
66
+ # are deeply rejected by Gradio's internal Canvas shadow properties.
67
+ CSS_STYLE = """
68
+ .gradio-image-hook, .gradio-image-hook * {
69
+ cursor: crosshair !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
  """
72
+
73
  # -----------------------------
74
 
75
  def get_model():
 
173
  # Paste original color into the highlighted region
174
  patch_crop = orig_pil.crop(box)
175
  temp_img.paste(patch_crop, box)
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  return np.array(temp_img), positions
178
 
 
269
  canvas_y = int(x_orig * ratio) + state['y_offset']
270
  canvas_x = int(y_orig * ratio) + state['x_offset']
271
 
272
+ # 1px flexible precision anchoring the patch directly onto the exact center click
273
+ px = max(0, min(int(canvas_x - PATCH_SIZE / 2), TARGET_CANVAS_SIZE - PATCH_SIZE))
274
+ py = max(0, min(int(canvas_y - PATCH_SIZE / 2), TARGET_CANVAS_SIZE - PATCH_SIZE))
275
 
276
  cur_loc = state['cur_location'].to(device) if state['cur_location'] is not None else None
277
  loc_tensor = torch.tensor([[px, py]], dtype=torch.long, device=device)
 
323
 
324
  return grey_base_np, {"Cleared": 1.0}, init_state_for_image(original_image), "Selections cleared. Ready for new patch sequence."
325
 
326
+ with gr.Blocks(title="MambaEye Interactive Demo", css=CSS_STYLE) as demo:
327
  gr.Markdown("# MambaEye Interactive Inference Demo")
328
  gr.Markdown("This interface incorporates the full **MambaEye-base** model natively.")
329
 
 
375
  outputs=[input_image, model_output_label, state, status_text]
376
  )
377
 
 
 
378
  if __name__ == "__main__":
379
  demo.launch(theme=gr.themes.Soft(), ssr_mode=False)