"""OracleZoom demo: upload a photo, watch it zoom 4x to 256x."""
import gradio as gr
import spaces
from PIL import Image, ImageDraw
import geometry
import video
import zoom
MODELS = zoom.Models()
UPSCALE = 4
ACCENT = "#f5b942"
LABELS = {1: "input", 4: "4x", 16: "16x", 64: "64x", 256: "256x"}
SAMPLES = ["0479", "0064", "0245", "0393", "0457"]
# Shipped output of a real run, so the page shows the payoff before anyone spends any quota.
EXAMPLE_CLIP = "samples/example_zoom.mp4"
EXAMPLE_LEVELS = [("samples/example_1x.png", "input")] + \
[(f"samples/example_{f}x.png", f"{f}x") for f in (4, 16, 64, 256)]
EXAMPLE_COMPARE = ("samples/example_256x_input.png", "samples/example_256x.png")
EXAMPLE_NOTE = "_An example run. Upload a photo above to make your own._"
HEADER = """
OracleZoom 🔎
Zoom into any photo far past what it holds. Four steps of 4x take you to
256x, each one drawn from the last.
Paper ·
Code ·
Project page ·
Model
"""
HOW = """
##### How it goes
1. Crop your photo to a 512 square.
2. Zoom 4x into the amber box. That crop is blurry, so a vision language model describes it.
3. Super-resolve it with that description as the guide.
4. Repeat on the result. Four rounds reach 256x.
Runs free on ZeroGPU, so the first zoom after a quiet spell waits for a GPU.
"""
FOOTER = """
### What you are looking at
Standard super-resolution models break down well before 16x. OracleZoom gets to 256x by
zooming one 4x step at a time and feeding each result into the next step. At every step a
vision language model writes a short description of the crop, and that description guides
the detail the super-resolution model draws.
Past the first step or two there is no ground truth to recover, so the deep levels are
**plausible detail, not measured detail**. The zoom point is a crop of your photo, not a
real camera lens moving closer. Read the paper for what we do and do not claim.
```bibtex
@inproceedings{dipta2027oraclezoom,
title = {OracleZoom: Reference-Constrained Recursive Super-Resolution},
author = {Roy Dipta, Shubhashis and Saha, Sourajit and Saha, Shaswati and Sarwar, Nobin},
year = {2027}
}
```
"""
CSS = """
#hero video {border-radius:12px}
.contain {max-width:1400px !important}
footer {display:none !important}
"""
def preview(image, levels, cx, cy):
"""Show where the zoom will go, so nobody spends a run to find out."""
if image is None:
return None
canvas = geometry.resize_and_center_crop(image).convert("RGB")
rects = geometry.nested_rects(canvas.size, int(levels), UPSCALE, (cx, cy))
dimmed = Image.blend(canvas, Image.new("RGB", canvas.size, (0, 0, 0)), 0.45)
dimmed.paste(canvas.crop(rects[0]), rects[0][:2])
draw = ImageDraw.Draw(dimmed)
for rect in rects:
if rect[2] - rect[0] >= 3:
draw.rectangle(rect, outline=ACCENT, width=2)
return dimmed
def pick_point(evt: gr.SelectData):
x, y = evt.index
return x / geometry.PROCESS_SIZE, y / geometry.PROCESS_SIZE
def estimate_duration(image, levels, cx, cy):
# Checked against the visitor's remaining quota BEFORE the run, so a loose number locks
# out low-quota visitors, and a tight one gets the run killed mid-way. Provisional until
# measured on the real hardware.
return int(15 + 9 * int(levels))
def _stream(image, levels, cx, cy):
if image is None:
raise gr.Error("Upload a photo first.")
levels = int(levels)
gallery, prompts, frames, compare = [], [], [], None
for step, factor, prompt, blurry, result in zoom.zoom(MODELS, image, levels, UPSCALE, (cx, cy)):
frames.append(result)
gallery.append((result, LABELS.get(factor, f"{factor}x")))
if step:
compare = (blurry, result)
prompts.append(f"**{LABELS[factor]}** {prompt or '_(no prompt)_'}")
left = levels - step
if not step:
status = f"Warmed up. Zooming {levels} step{'s' if levels > 1 else ''}…"
elif left:
status = f"At **{LABELS[factor]}**, {left} step{'s' if left > 1 else ''} to go…"
else:
status = f"At **{LABELS[factor]}**. Rendering the clip…"
# First yield clears any clip left from the previous run; later ones leave it alone.
yield status, (None if not step else gr.skip()), gallery, compare, "\n\n".join(prompts)
yield ("Done. 🔎", video.render(frames, UPSCALE, (cx, cy)), gallery, compare,
"\n\n".join(prompts))
@spaces.GPU(duration=estimate_duration)
def run(image, levels, cx, cy):
yield from _stream(image, levels, cx, cy)
@spaces.GPU(duration=estimate_duration(None, 4, 0, 0))
def run_example(image):
"""One input, so the examples render as thumbnails instead of a four-column table.
Its results are cached, which is how a visitor with no quota left still sees output."""
yield from _stream(image, 4, 0.5, 0.5)
with gr.Blocks(theme=gr.themes.Soft(primary_hue="amber"), css=CSS,
title="OracleZoom: zoom to 256x") as demo:
gr.HTML(HEADER)
with gr.Row():
with gr.Column(scale=4):
image = gr.Image(label="Your photo", type="pil", height=300, sources=["upload", "clipboard"])
# Seeded with the example so the box overlay explains itself before any upload.
target = gr.Image(value=preview(Image.open(EXAMPLE_LEVELS[0][0]), 4, 0.5, 0.5),
label="Click to move the zoom point", type="pil",
interactive=False, height=340, show_download_button=False)
levels = gr.Slider(1, 4, value=4, step=1, label="Zoom steps",
info="1 step = 4x, 4 steps = 256x. Fewer steps finish sooner.")
with gr.Accordion("Set the point by hand", open=False):
cx = gr.Slider(0, 1, value=0.5, step=0.01, label="Horizontal")
cy = gr.Slider(0, 1, value=0.5, step=0.01, label="Vertical")
go = gr.Button("🔎 Zoom in", variant="primary", size="lg")
gr.Markdown(HOW)
with gr.Column(scale=6):
status = gr.Markdown("Upload a photo, then press **Zoom in**.")
clip = gr.Video(value=EXAMPLE_CLIP, label="The zoom", elem_id="hero", autoplay=True,
loop=True, show_share_button=True, height=400)
gallery = gr.Gallery(value=EXAMPLE_LEVELS, label="Every level", columns=5, height=175,
object_fit="cover", show_download_button=True)
compare = gr.ImageSlider(value=EXAMPLE_COMPARE, height=400,
label="256x: plain enlargement (left) vs OracleZoom (right)")
gr.Markdown("##### What the model said it saw, step by step")
prompts = gr.Markdown(EXAMPLE_NOTE)
controls = [image, levels, cx, cy]
for c in controls:
c.change(preview, controls, target, show_api=False)
target.select(pick_point, None, [cx, cy], show_api=False)
go.click(run, controls, [status, clip, gallery, compare, prompts])
gr.Examples(
examples=[f"samples/{n}.png" for n in SAMPLES],
inputs=[image],
outputs=[status, clip, gallery, compare, prompts],
fn=run_example,
cache_examples=True,
label="Or try one of these (already computed, costs you nothing)",
)
gr.Markdown(FOOTER)
if __name__ == "__main__":
demo.queue(max_size=20).launch()