Include JS zoom
Browse files- app.py +57 -2
- launch.sh +1 -1
- requirements.txt +1 -1
app.py
CHANGED
@@ -67,6 +67,7 @@ def update_rankings_table():
|
|
67 |
rankings.sort(key=lambda x: x[1], reverse=True)
|
68 |
return rankings
|
69 |
|
|
|
70 |
def select_new_image():
|
71 |
"""Select a new image and its segmented versions."""
|
72 |
max_attempts = 10
|
@@ -141,9 +142,59 @@ def compute_mask_difference(segmented_a, segmented_b):
|
|
141 |
# Compute the absolute difference between the masks
|
142 |
return np.abs(mask_a_1d - mask_b_1d)
|
143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
def gradio_interface():
|
145 |
"""Create and return the Gradio interface."""
|
146 |
-
with gr.Blocks() as demo:
|
147 |
gr.Markdown("# Background Removal Arena")
|
148 |
button_name = "Difference between masks"
|
149 |
|
@@ -277,7 +328,7 @@ def gradio_interface():
|
|
277 |
state_segmented_a, state_segmented_b, notice_markdown
|
278 |
]
|
279 |
)
|
280 |
-
|
281 |
|
282 |
def handle_zoom(current_image, zoomed_state_input, original_image, other_image, event: gr.SelectData):
|
283 |
"""Toggle between zoomed and original image based on click events."""
|
@@ -462,7 +513,11 @@ def schedule_dump_database(interval=60):
|
|
462 |
else:
|
463 |
logging.info("Not running in Hugging Face Spaces. Database dump scheduler not started.")
|
464 |
|
|
|
|
|
|
|
465 |
if __name__ == "__main__":
|
466 |
schedule_dump_database() # Start the periodic database dump
|
467 |
demo = gradio_interface()
|
|
|
468 |
demo.launch()
|
|
|
67 |
rankings.sort(key=lambda x: x[1], reverse=True)
|
68 |
return rankings
|
69 |
|
70 |
+
|
71 |
def select_new_image():
|
72 |
"""Select a new image and its segmented versions."""
|
73 |
max_attempts = 10
|
|
|
142 |
# Compute the absolute difference between the masks
|
143 |
return np.abs(mask_a_1d - mask_b_1d)
|
144 |
|
145 |
+
js = r"""
|
146 |
+
function load_zoom() {
|
147 |
+
setTimeout(function() {
|
148 |
+
|
149 |
+
// Select all images from the three displayed image containers.
|
150 |
+
const images = document.querySelectorAll('.image-container img');
|
151 |
+
|
152 |
+
// Set transform origin so scaling and translating feels "natural".
|
153 |
+
images.forEach(img => {
|
154 |
+
img.style.transformOrigin = 'top left';
|
155 |
+
img.style.transition = 'transform 0.1s ease-out';
|
156 |
+
img.style.cursor = 'zoom-in';
|
157 |
+
});
|
158 |
+
|
159 |
+
// Choose a scale factor
|
160 |
+
const scale = 2;
|
161 |
+
|
162 |
+
function handleMouseMove(e) {
|
163 |
+
const rect = e.currentTarget.getBoundingClientRect();
|
164 |
+
const xPercent = (e.clientX - rect.left) / rect.width;
|
165 |
+
const yPercent = (e.clientY - rect.top) / rect.height;
|
166 |
+
const offsetX = xPercent * (scale - 1) * 100;
|
167 |
+
const offsetY = yPercent * (scale - 1) * 100;
|
168 |
+
|
169 |
+
images.forEach(img => {
|
170 |
+
img.style.transform = `translate(-${offsetX}%, -${offsetY}%) scale(${scale})`;
|
171 |
+
});
|
172 |
+
}
|
173 |
+
|
174 |
+
function handleMouseEnter(e) {
|
175 |
+
e.currentTarget.addEventListener('mousemove', handleMouseMove);
|
176 |
+
}
|
177 |
+
|
178 |
+
function handleMouseLeave(e) {
|
179 |
+
e.currentTarget.removeEventListener('mousemove', handleMouseMove);
|
180 |
+
images.forEach(img => {
|
181 |
+
img.style.transform = 'translate(0,0) scale(1)';
|
182 |
+
});
|
183 |
+
}
|
184 |
+
|
185 |
+
const containers = document.querySelectorAll('.image-container');
|
186 |
+
|
187 |
+
containers.forEach(container => {
|
188 |
+
container.addEventListener('mouseenter', handleMouseEnter);
|
189 |
+
container.addEventListener('mouseleave', handleMouseLeave);
|
190 |
+
});
|
191 |
+
}, 1000); // 1 second timeout
|
192 |
+
}
|
193 |
+
"""
|
194 |
+
|
195 |
def gradio_interface():
|
196 |
"""Create and return the Gradio interface."""
|
197 |
+
with gr.Blocks(js=js) as demo:
|
198 |
gr.Markdown("# Background Removal Arena")
|
199 |
button_name = "Difference between masks"
|
200 |
|
|
|
328 |
state_segmented_a, state_segmented_b, notice_markdown
|
329 |
]
|
330 |
)
|
331 |
+
|
332 |
|
333 |
def handle_zoom(current_image, zoomed_state_input, original_image, other_image, event: gr.SelectData):
|
334 |
"""Toggle between zoomed and original image based on click events."""
|
|
|
513 |
else:
|
514 |
logging.info("Not running in Hugging Face Spaces. Database dump scheduler not started.")
|
515 |
|
516 |
+
|
517 |
+
|
518 |
+
|
519 |
if __name__ == "__main__":
|
520 |
schedule_dump_database() # Start the periodic database dump
|
521 |
demo = gradio_interface()
|
522 |
+
|
523 |
demo.launch()
|
launch.sh
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
pip3 install -r requirements.txt
|
2 |
-
|
|
|
1 |
pip3 install -r requirements.txt
|
2 |
+
gradio app.py
|
requirements.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
certifi==2024.8.30
|
2 |
fastapi==0.115.4
|
3 |
-
gradio==5.
|
4 |
numpy==2.0.2
|
5 |
pandas==2.2.3
|
6 |
pillow==11.0.0
|
|
|
1 |
certifi==2024.8.30
|
2 |
fastapi==0.115.4
|
3 |
+
gradio==5.8.0
|
4 |
numpy==2.0.2
|
5 |
pandas==2.2.3
|
6 |
pillow==11.0.0
|